我可以在声明之前访问静态块中的静态字段吗?

时间:2013-09-19 08:04:36

标签: java static static-block

我对下面的代码感到困惑我预计它会给出一个错误或答案是10但它会给出20个怎么样?

public class test {
    public static void main(String[] args) {
        System.out.println(x);
    }

    static{
        x=10;
    }

    static int x=20;
}

2 个答案:

答案 0 :(得分:8)

它在section 12.4.2 of the JLS中指定,它提供了类初始化的详细信息:

  

接下来,按文本顺序执行类的类变量初始值设定项和静态初始值设定项,或接口的字段初始值设定项,就像它们是单个块一样。

变量初始值设定项(x = 20)出现在程序文本中的静态初始值设定项(包含x = 10的块)之后。因此,初始化结束时的值为20。

如果您交换订单轮次以便变量初始化程序首先出现,那么您将看到10。

我强烈建议您尽可能避免编写依赖于文本排序的代码。

编辑:变量仍然可以在静态初始值设定项中使用因为它在范围内 - 就像你可以在早于变量声明的方法中使用实例变量一样。但是,section 8.3.2.3对此有一些限制:

  

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

     
      
  • 用法发生在C的实例(分别是静态)变量初始值设定项或C的实例(分别是静态)初始值设定项中。

  •   
  • 用法不在作业的左侧。

  •   
  • 用法是通过一个简单的名称。

  •   
  • C是封闭用法的最里面的类或接口。

  •   
     

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

因此,如果您将静态初始化程序更改为:

static {
    System.out.println(x);
}

然后你会收到错误。

您现有的静态初始化程序以符合所有限制的方式使用x

答案 1 :(得分:1)

在静态中,如果值被更改一次,那么它将通过out实现。 所以你得到20岁。

如果你这样写

public class test {
      static int x=20;

 public static void main(String[] args) {
 System.out.println(x);
            }
static{
x=10;
 }
  }
然后它将打印10。