2012-04-19 35 views
0

我知道靜態塊在任何事情之前運行。但是,在這裏,當調用B.test()時會發生什麼?執行和設置值的順序?後來,當b1設置爲null時,仍然如何b1.i評估爲20?執行順序,靜態塊,字段

class B 
{  
    static int i; 
    static { 
     i = 20; 
     System.out.println("SIB"); 
    } 
    static int test() { 
     int i = 24; 
     System.out.println(i); 
     return i; 
    } 
} 

public class Manager { 
    public static void main(String[] arg) { 
     B.test(); 
     B b1 = null; 
     System.out.println(b1.i); 
    } 
} 

的輸出是:

SIB 
24 
20 
+0

B.test沒有設置任何靜態或實例變量,因此調用那就沒有長期效果。 (仔細閱讀它。) – 2012-04-19 20:28:58

+0

順便說一句,從非靜態引用(如b1實例)訪問靜態成員是一種不好的做法。 – garbagecollector 2012-04-19 20:31:24

回答

3

i是靜態的,所以b1.i相當於B.i。只需將b1設置爲null不會更改任何靜態變量。

當調用B.test()時,首先加載B類,然後運行靜態塊。接下來,B.test()創建一個新方法 - 局部變量,稱爲i,它與B.i完全不同。這個新的本地i已打印並返回。 B.i肯定是不是因爲你創建了一個新的B對象引用,它是空的 - 這對任何東西都沒有任何影響。

+0

謝謝,但是當b1設置爲null時,它應該存儲,指向無。不應該b1.i給出nullPointerException,因爲b1沒有引用任何內容,它不會引用像i或其他字段這樣的內部值? – onlinenaman 2012-04-19 20:39:08

+1

引用靜態字段就好像它們是實例變量一樣有趣,但基本上,如果引用'instance.staticField',它將完全忽略'instance'的值 - 即使它爲null。 – 2012-04-19 23:26:30

1

但是在這裏,當調用B.test()時會發生什麼?執行和設置值的順序?

沒有變化。

後來,當b1設置爲null時,b1.i的計算結果仍爲20?

因爲b1不使用,該字段是靜態的,所以你實際上是使用B.i

5

i這裏的價值

static int i; 
static { 
    i = 20; 
    System.out.println("SIB"); 
} 

設置爲20,從來沒有修改,所以當你訪問b1.i,它仍然是20

在您的test()方法中,您正在使用另一個與靜態無關的變量i

1

會發生什麼事是:

  • B.test()被稱爲首次,實際運行它之前:
  • B被加載,
  • 靜態初始化執行(B.i = 20現在)
  • 內容的B.test()方法執行
  • (創建一個方法本地int i = 24(它陰影靜態變量B.i)並打印出來)
  • b1.i被解釋爲B.i(它仍然是20)並且已打印。
+0

謝謝,但是當b1設置爲null時,它應該存儲,指向無。不應該b1.i給出nullPointerException,因爲b1沒有引用任何內容,它不會引用像i或其他字段這樣的內部值? b1.i - > null.i? – onlinenaman 2012-04-19 20:46:26

+1

不,您正在訪問一個靜態變量,它存儲在類中,而不是實例中。編譯器實際上只是查看'b1'類,並發現你正在訪問'B.i'。它從不試圖對實例做任何事情。 – trutheality 2012-04-19 21:11:19

1
What you did:    What really happened: 
B.test()     - static block of class B is run, static i set to 20, SIB is displayed 
          - test method is called, local property i set to 24, 24 is displayed 
b1 = null     - set reference for b1 to null. Note that this doesn't change the value of class B's static properties 
System.out.println(b1.i) - b1 is still Class B. It doesn't matter what its current reference is. Static i for class B is still 20, 20 is displayed