2010-11-22 103 views
18

我一直在使用Java很長一段時間,但從來沒有遇到過這樣的事情。 我想知道它是什麼以及它爲什麼不是錯誤。Java獨立代碼塊

public class Foo{ 

private int someVariable; 

{ 
    doSomething(); 
} 

public Foo(){ 
} 

private void doSomething(){ 
    // Something is done here 
} 

} 

我想知道包含對「doSomething()」的調用的單個塊的目的是什麼。 它只是一個骨架代碼。我遇到的實際代碼是http://www.peterfranza.com/2010/07/15/gwt-scrollpanel-for-touch-screens/

+0

由於兩者的u ...那是真正有用的...是以前一無所知...... – Kasturi 2010-11-22 20:35:49

回答

28

這是一個(非靜態)初始化塊。據記載在官方教程here

初始化實例成員

通常情況下,你乾脆把代碼在構造函數初始化實例變量。使用構造函數初始化實例變量有兩種選擇:初始化塊和最終方法。 初始化語句塊實例變量看起來就像靜態初始化塊,但沒有static關鍵字:

{ 
    // whatever code is needed for initialization goes here 
} 

Java編譯器副本初始化語句塊到每一個構造函數。因此,這種方法可以用來在多個構造函數之間共享一段代碼。


下面是一個簡單的演示:

public class Test { 

    { 
     System.out.println("Initializer block"); 
    } 

    Test() { 
     System.out.println("Constructor 1"); 
    } 

    Test(int i) { 
     System.out.println("Constructor 2"); 
    } 

    public static void main(String[] args) { 
     new Test(); 
     System.out.println("---"); 
     new Test(1); 
    } 
} 

輸出

Initializer block 
Constructor 1 
--- 
Initializer block 
Constructor 2 

你會發現這個有用的,當例如添加JLabel到面板:

panel.add(new JLabel() {{ setBackground(Color.GREEN); setText("Hello"); }}); 

引擎蓋下:

初始化塊的字節碼被逐字拷貝到每個構造。 (至少太陽的javac和Eclipse編譯:

Test(); 
    Code: 
    0: aload_0 
    1: invokespecial 
    4: getstatiC#2; 
    7: ldC#3;   //String "Initializer block" 
    9: invokevirtual #4; //Method PrintStream.println:(String;)V 
    12: getstatiC#2; 
    15: ldC#5; 
    17: invokevirtual #4; 
    20: return 

Test(int); 
    Code: 
    0: aload_0 
    1: invokespecial #1; 
    4: getstatiC#2; 
    7: ldC#3;   //String "Initializer block" 
    9: invokevirtual #4; //Method PrintStream.println:(String;)V 
    12: getstatiC#2; 
    15: ldC#6; 
    17: invokevirtual #4; 
    20: return 
+3

注意它的運行* *前的構造函數的代碼,所以不要依賴於在構造函數中完成的事情。 – 2010-11-22 20:26:01

7

這是一個初始化塊,它被複制到類的所有構造函數中。