2011-05-03 67 views
24

我准备了Java认证考试,我已经在实践检验的一个见过这样的代码:为什么此Java代码在方括号外的大括号({})中?

class Foo { 
    int x = 1; 
    public static void main(String [] args) { 
     int x = 2; 
     Foo f = new Foo(); 
     f.whatever(); 
    } 
    { x += x; } // <-- what's up with this? 
    void whatever() { 
     ++x; 
     System.out.println(x); 
    } 
} 

我的问题是......它是有效的写在大括号中的代码的方法外?这些(如果有的话)有什么影响?

+2

参见[8.6实例初始值设定(http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.6 )。 – trashgod 2011-05-03 04:43:40

+0

斯蒂芬,它可能因为话题而重复,但我以完全不同的方式得到了这个 – nairdaen 2011-05-03 04:52:02

+2

正如其他人所指出的那样,这是有效的。然而,在你的生活中的某个时候,你会在获得Java认证后进行编程。请不要在日常工作中使用这种结构。请。我讨厌Java认证。它教会了你所有令人不安的错综复杂的,有时是微妙的方式来混淆你的同事和引入错误。 – rfeak 2011-05-03 05:17:20

回答

31

here借 -

通常情况下,你干脆把代码放在一个 构造函数初始化实例变量。有两种方法可以使用构造函数来初始化实例变量:初始化块和最终方法。 初始化语句块实例变量看起来就像静态初始化 块,但没有static关键字:

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

Java编译器副本初始化语句块到每一个构造函数。因此,这种方法可以用来在多个构造函数之间共享一段代码。

您可能还想看看讨论here

+0

我有一个问题,为什么这个代码从来没有执行过... ... {} {System.out.println(“com.test.BaseClazz.initial”); } – Omer 2016-12-01 21:31:03

6

这是一个initializer block。它用于设置实例变量。在构造函数中使用初始化块的动机是为了防止编写冗余代码。 Java编译器将块的内容复制到每个构造函数中。

8

这是一个初始化块,在类的实例被加载/创建时执行,并用于初始化类的成员属性(请参阅Java http://download.oracle.com/javase/tutorial/java/javaOO/initial.html)。您可以根据需要拥有尽可能多的块,并且会从顶部到底部实例化。

除了实例块之外,还可以根据需要使用尽可能多的静态块以及初始化静态成员。他们将如下声明:

public class Initialization { 

    static int b = 10; 

    int a = 5; 

    static { 
     b = -9; 
    } 

    { 
     a += 2; 
    } 

    public static void main(String[] args) throws Exception { 

     System.out.println(ClientVoting.b); 
     System.out.println(new ClientVoting().a); 
     System.out.println(ClientVoting.b); 
     System.out.println(new ClientVoting().a); 

    } 

    static { 
     b = 1; 
    } 

    { 
     a++; 
    } 
} 

虽然类正在初始化,静态部件“b”被作为10初始化,则第一个静态范围其值更改为-9,后来为1。这仅在类加载时执行一次。这在main方法的第一行初始化之前执行。

另一方面,与您的类相似的示例是实例引用“a”。 A初始化为5,然后实例块将其更新为7,最后一个块更新为8.如预期的那样,静态成员仅在此代码中初始化一次,而实例块在每次创建新实例时执行。

输出到本实施例中是1 8 1 8