静态块初始化

时间:2012-12-02 16:34:18

标签: java static instance

这是一段Java代码:

static {        
    ture = 9;       
}
static int ture;
{ // instance block 
    System.out.println(":"+ture+":");           
}

它是如何编译的?初始化后已执行变量'ture'的声明。据我所知,静态块和字段按它们出现的顺序执行。

现在为什么实例块中的值9已被打印3次?顺便说一下,类的实例已经创建了3次。 这不是作业,我正在学习Java认证。

3 个答案:

答案 0 :(得分:11)

关于第一个问题,静态块确实按它们出现的顺序处理,但是在静态块之前首先处理声明。声明作为类(JLS §12.3.2)的准备的一部分进行处理,该准备初始化JLS §12.4.2)之前发生。出于学习目的,整个JLS §12可能很有用,以及JLS §8,尤其是§8.6JLS §8.7(感谢Ted Hoppirreputable调用这些部分。)

您的引用代码中没有足够的信息来回答您的第二个问题。 (无论如何,在每个问题上最好问一下一个问题。)但是例如:

public class Foo {
    static {     
        ture = 9;   
    }

    static int ture;

    {   // instance block   
        System.out.println(":"+ture+":");

    }

    public static final void main(String[] args) {
        new Foo();
    }
}

...仅输出:9: 一次,因为只创建了一个实例。如果删除new Foo();行,它根本不会输出它。如果您看到:9:三次,那么您可能会在未显示的代码中创建三个实例。

答案 1 :(得分:2)

静态初始化程序按它们出现的顺序执行,而声明根本不执行,这就是它们的名称。这就是为什么你的代码编译没有问题的原因:类结构在编译时从声明组装,静态块在运行时执行,很久就在处理完所有声明之后。

答案 2 :(得分:2)

正如其他人所说,声明的地方通常是无关紧要的。

但有时可能引起混淆:

class Z {
    static int i = j + 2;  // what should be the value of j here?
    static int j = 4;
}

所以Java确实在前向引用上添加了一些限制: http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.3.2.3

您的示例是允许的,因为该字段的使用位于作业的左侧。显然,语言设计师并不认为这太混乱了。然而,如果可以的话,我们应该总是避免前向参考。