Java解惑五:類之謎

weixin_34162629發表於2014-07-13
本文是依據JAVA解惑這本書,做的筆記。電子書見:http://download.csdn.net/detail/u010378705/7527721

謎題46

函式過載的問題。
JAVA過載解析過程:1. 選取全部可用的方法或者構造器;2. 從過程1中選取的方法或構造器中選擇最精確的。
一般而言:能夠強制要求編譯器選擇一個精確的過載版本號,將實參轉型為形參所宣告的型別。

謎題47

繼承中靜態域的問題。
靜態域由宣告它的類及其全部子類共享。
假設須要讓每個子類都具有某個域的單獨拷貝,必須在每個子類中宣告一個單獨的靜態域。
假設每個例項都須要一個單獨的拷貝,則能夠在基類中宣告一個非靜態域。

謎題48

靜態方法的問題。
對靜態方法的呼叫不存在不論什麼動態分配機制。靜態方法是編譯時刻選定的,依據修飾符編譯期型別選定的。
靜態方法不能被覆寫,僅僅能被隱藏。
儘量使用類名來呼叫靜態方法。

謎題49

public class Elvis {	
	public static final Elvis INSTANCE = new Elvis();
	private final int beltSize;
	private static final int YEAR = Calendar.getInstance().get(Calendar.YEAR);
	private Elvis() {
		beltSize = YEAR - 1930;
	}
	public int beltSize() {
		return beltSize;
	}
	public static void main(String[] args) {
		System.out.println(INSTANCE.beltSize());
	}
}
初始化的問題。
final型別的靜態域被初始化之前存在被讀取的可能,此時該靜態域僅僅是所屬型別的預設值。
final型別的域僅僅有在初始化表示式是常量表示式時,才是常量。
類的初始化迴圈有待進一步理解。

謎題50

instanceof的問題
當instanceof左運算元為null時,返回false。
當instanceof左右運算元都是類的時候,當中一個必須是還有一個的子型別,否則編譯錯誤。
轉型操作符的行為與instanceof同樣,當轉型操作的兩種型別都是類時,必須當中一個是還有一個子型別。

謎題51

class Point {
	protected final int x, y;
	private final String name;
	Point(int x, int y) {
		this.x = x;
		this.y = y;
		name = makeName(); // 3. 呼叫子類的方法。
	}
	protected String makeName() {
		return "[" + x + "," + y + "]";
	}
	public final String toString() {
		return name;
	}
}
public class ColorPoint extends Point{
	private final String color;
	ColorPoint(int x, int y, String color) {
		super(x, y); //2. 轉向父類的建構函式。
		this.color = color; // 5. 初始化該屬性。
	}
	protected String makeName() {
		//4.在子類的建構函式結束前執行。
		return super.makeName() + ":" + color;
	}
	public static void main(String[] args) {
		//1. 呼叫子類的建構函式。
		System.out.println(new ColorPoint(1, 2 , "red"));
	}
}
建構函式呼叫了子類覆寫的方法。
例項初始化迴圈,能夠採用惰性初始化。

謎題52

class Cache {	
	static {
		initializedIfNecessary();
	}
	private static int sum;
	public static int getSum() {
		initializedIfNecessary();
		return sum;
	}
	private static boolean initialized = false;
	private static synchronized void initializedIfNecessary() {
		if (! initialized) {
			for (int i = 0; i < 100; i++) {
				sum += i;
			}
			initialized = true;
		}
	}
}
public class Client {
	public static void main(String[] args) {
		System.out.println(Cache.getSum());
	}
}
同一時候使用了惰性初始化和積極初始化。
初始化順序對結果的影響。
改動後的程式
class Cache {	
	private static final  int sum = computeSum();
	private static int computeSum() {
		int result = 0;
		for (int i = 0; i < 100; i++) {
			result += i;
		}
		return result;
	}
	public static int getSum() {
		return sum;
	}
}

謎題53

講述了私有構造器捕獲慣使用方法。
<span style="font-size:18px;">class Thing {
	public Thing(int i) {
		System.out.println("Thing:" + i);
	}
}
public class MyThing extends Thing {
	@SuppressWarnings("unused")
	private final int arg;
	public MyThing() {
		this(1);//能夠呼叫其它類的方法獲取返回值。
	}
	private MyThing(int i) {
		super(i);
		arg = i;
	}
}</span>

謎題54

靜態方法呼叫時,例項不起作用。靜態方法是屬於類的。

謎題55

java語言規範不同意一個本地變數宣告語句作為一條語句在迴圈中反覆執行。一個本地變數宣告作為一條語句,僅僅能直接出如今一個語句塊中(花括號裡的)。
for (int i = 0; i < 10; i++)
String str = "123";
這個編譯不通過,改動正確為:
for (int i = 0; i < 10; i++) {
Stirng str = "123";
}

相關文章