第一題 下列代碼輸入什麼? public class Test { public static Test t1 = new Test(); { System.out.println("blockA"); } static { System.out.println("blockB"); } publi ...
第一題 下列代碼輸入什麼?
public class Test {
public static Test t1 = new Test();
{
System.out.println("blockA");
}
static {
System.out.println("blockB");
}
public static void main(String[] args) {
Test t2 = new Test();
}
}
解析:
本題考察類載入。
根據跟蹤源代碼可知,執行main方法之前,Test類就已經載入完畢,也就是說,執行到Test t2 = new Test();
的時候,控制台已經列印了blockAblockB
。
可以在第4,7,11,15行都打上斷點,可以看到程式一開始是從第4行開始執行的。這就說明Test類的載入先於main方法。
創建t2時,再去Test類中執行一次非靜態代碼塊和構造方法,因為沒有自定義構造方法,所以只輸出非靜態代碼塊的內容。
如果有自定義構造方法,那麼先執行非靜態代碼塊,然後執行構造方法。為什麼?因為構造方法可能會用到代碼塊里的東西。把構造方法比喻成吃飯,那麼非靜態代碼塊就是把飯菜端到桌子上或者盛到碗里。
而靜態域和靜態代碼塊的優先順序就更高了,他倆相當於把飯做好。他倆之間的優先順序是:誰先被定義,誰就先被執行。在這道題目中,t1的優先順序就比靜態代碼塊高。大家可以把他倆的位置換一下,輸出的內容一定是
blockB
blockA
blockA
靜態域和靜態代碼塊只會執行一次(類載入時)。
非靜態域和非靜態代碼塊每次創建對象時都會被執行。
答案:
blockA
blockB
blockA
第二題 下列代碼輸出什麼?
public class Test2 {
public static void main(String[] args) {
test();
}
public static void add(Byte b) {
b = b++;
}
public static void test() {
Byte a = 127;
Byte b = 127;
add(++a);
System.out.print(a + " ");
add(b);
System.out.print(b + "");
}
}
解析:
add(++a)
:先把a轉成byte,然後用a的補碼+1,因為byte類型範圍是:[-128,127],所以加1後,a=-128。再將a轉為Byte類型,此時才開始調用add(-128),執行過程是這樣的:
由圖可知,執行b++
之後,add方法中的b會指向其他對象,那麼,紅線就會斷開。所以,add方法不會對main中的變數產生影響。所以a=-128,b=127。
答案:
-128 127