如何在静态变量和块之间执行执行顺序?

时间:2014-03-25 11:34:04

标签: java static scope static-variables static-block

考虑以下情况:
码: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是真的吗?

3 个答案:

答案 0 :(得分:3)

来自Java Language Specification §8.3.2.3

  

成员声明只有在成员是类或接口C的实例(分别是静态)字段并且满足以下所有条件时才需要以文本方式显示:

     
      
  • 用法发生在C的实例(分别是静态)变量初始化程序或C的实例(分别是静态)初始化程序中。
  •   
  • 用法不在作业的左侧。
  •   
  • 使用方法是一个简单的名称。
  •   
  • C是封闭用法的最里面的类或接口。
  •   
     

如果不满足上述四项要求中的任何一项,则为编译时错误。

     

[...]

     

上述限制旨在在编译时捕获循环或其他格式错误的初始化

换句话说,可以到稍后在类中声明的字段,但不能从读取

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

答案 1 :(得分: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)说,在使用字段之前,必须执行初始化程序(块和字段初始化程序)。

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

答案 2 :(得分:-1)

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

  

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

您尝试在声明变量之前使用变量。 BTW没有在运行时抛出错误。这是编译器错误。