2014-03-25 29 views
5

考虑下面的情形:
码:1执行顺序如何在静态变量和块之间执行?

public class StaticDemo { 
    static{ 
     b=5; 
     System.out.println("Static B:"+b);/*Compilation error:"Cannot reference a field before it is defined"*/ 
    } 
    static int b; 
    static{ 
     System.out.println("B:"+b); 
    } 
    public static void main(String[] args) {  
    } 
} 

注释的代码如下,有没有错误,下面的输出已显示。
码:2

public class StaticDemo { 
    static{ 
     b=5; 
     //System.out.println("Static B:"+b); 
    } 
    static int b; 
    static{ 
     System.out.println("B:"+b); 
    } 
    public static void main(String[] args) {  
    } 
} 

输出 -

B:5 

如果执行基于在其中静态变量或块已被写入的顺序上。

  1. 为什么不抛出初始化中的代码所示(b=5) 编译错误:2。

  2. 也请解释为什么错误被抛出代码:1,如果 代码:2是真的吗?

+0

这个问题的答案 http://stackoverflow.com/questions/16635200/java-accessing-static-variables-inside-static-block – Oliver

回答

3

从构件的Java Language Specification §8.3.2.3

声明需要以文本方式显示用于仅当所述构件(分别静态)是一个实例的类或接口的C字段之前它和所有的以下条件持有:在一个实例(分别静态)C的或在一个实例变量初始化发生

  • 用法C.
  • 的(分别为静态)初始化的使用不是在赋值的左手侧。
  • 用法是通过一个简单的名字。
  • C是封闭使用的最内层的类或接口。

如果以上四项要求中的任何一项未得到满足,这是编译时错误。

[...]

的限制上述被设计为捕获,在编译时,圆形或其他格式错误初始化

换句话说,它是确定以写入到现场这是后来在课堂上宣布的,但不是从它读取

在引用的部分后面的示例框中有更详细的示例。

+0

+1:打败我吧。刚花了10分钟寻找一个链接到规格>。< –

+0

@ ian-roberts非常感谢。 – Vasanth

+0

@Vasanth - 如果你发现一个有用的答案,不要忘记也upvote。 :) –

-1

执行顺序是从上到下。声明之前,您不能使用静态字段。

为什么被抛出代码错误:1,如果代码:2是真的

试图使用一个变量被宣布之前。 BTW没有在运行时抛出错误。这是一个编译器错误。

+2

如果代码是从底部,你如何分配一个值给一个尚未声明的变量? –

+0

准确。必须承认我不知道这是可能的。 “代码2”的确编译,而“代码1”则没有。 –

+0

已声明,在运行静态块之前识别类变量。 –

2

在第一个示例中,变量b由第一个要执行的静态块初始化。编译器不记得第一行,因此在静态块的第二行,它抱怨引用b,因为'b'可能尚未初始化。

当编译器通过b的定义时,他确信b已初始化。因此你的代码被允许引用/访问它。

在源代码发生之前初始化一个静态变量是好的,但只有在它发生后才允许访问它。

如果咨询Java Specification它规定了以下内容:

Initialization of a class consists of executing its static initializers and the initializers for static fields (class variables) declared in the class. 

A class or interface type T will be initialized immediately before the first occurrence of any one of the following: 
    1) A static field declared by T is assigned. 
    2) A static field declared by T is used and the field is not a constant variable (§4.12.4). 

1)说,一个静态初始化直接分配静态字段之前执行。 2)说,在你可以使用一个字段之前,初始值设定项(块和字段初始值设定项)必须已被执行。

因此,您可以为静态初始化块中的静态字段赋值,但在完成所有初始化之前无法使用它。这就是我的理解。

+0

**在源代码发生之前初始化一个静态变量是好的,但只有在它发生后才允许访问它。** 我能够得到你想说的。但是,您能否提供解释这种情况的任何链接或来源。这将是非常有帮助的。 – Vasanth