2010-11-22 70 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

这是一个初始化块,它被复制到类的所有构造函数中。