Java静态final字段初始化顺序 [英] Java static final field initialization order

查看:423
本文介绍了Java静态final字段初始化顺序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图理解初始化顺序的行为,当静态字段使用对同一封闭类对象的引用初始化时。

  public class Test {

static final Test t = new Test();
static int a = 5;

Test(){
System.out.println(a =+ a);
}

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

}

上述代码段的输出:

  a = 0 
a = 5

如果我修改变量 a 为除了 static

  static final a = 5; 
a = 5;
final a = 5;

输出为:

  a = 5 
a = 5



请注意,输出为 a = 5& a = 5 ,即使 t& a 声明为 static final ,在这种情况下 t $ c> a

解决方案

static final成员在其他静态成员之前初始化。



非最终静态成员按照出现顺序初始化



因此,在第一种情况下:

  static Test t = new Test(); 
static int a = 5;

a 之前首先调用构造函数初始化,因此显示 a = 0



t 之前初始化一个,因此当第一个实例时显示 a = 5 创建测试。当 a 不是静态的,它在执行构造函数之前被初始化,因此再次显示 a = 5



查看 docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.4.2rel =nofollow> JLS 的12.4.2:

$然后,初始化接口的最终类​​变量和字段,这些接口的值为编译时常量[] <$> <$> <$> <$>

<表达式
(§8.3.2.1,§9.3.1,§13.4.9,§15.28)。

...


  1. 接下来,按文本顺序执行类的类变量初始化器和静态初始化器,或接口的字段初始化器,就好像它们是单个块。


您会看到最终的类变量(即static final)变量(如果值是编译时间)常量表达式 5 是一个常量表达式。 new Test()不是。因此, a 在 t 之前初始化,即使两者都是静态final。


I tried to understand the behavior of initialization order when static fields are initialized with a reference to the same enclosing class object.

public class Test {

        static final Test t=new Test();
        static int a=5;

        Test(){
            System.out.println("a="+a);
        }

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

    }

Output of above piece of code is:

a=0
a=5

If I modify variable a to anything else other than plain static:

static final a=5;
a=5;
final a=5;

The output is:

a=5
a=5

Why is this behavior?

Note that the output is a=5 & a=5 even when both t & a are declared as static final in which case t precedes the declaration of a

解决方案

static final members are initialized before other static members.

non final static members are initialized in order of appearance

Therefore, in your first case :

    static Test t=new Test();
    static int a=5;

The constructor is first called before a is initialized, so a=0 is displayed.

In the second case, static final a is initialized before t, so a=5 is displayed when the first instance of Test is created. When a is not static, it is initialized prior to the execution of the constructor, so again a=5 is displayed.

Regarding the edit in your question.

Looking at section 12.4.2 of the JLS :

  1. Then, initialize the final class variables and fields of interfaces whose values are compile-time constant expressions (§8.3.2.1, §9.3.1, §13.4.9, §15.28).

...

  1. Next, execute either the class variable initializers and static initializers of the class, or the field initializers of the interface, in textual order, as though they were a single block.

You see that final class variables (i.e. static final) are initialized before the rest of the static variables only if their values are compile time constant expressions. 5 is a constant expression. new Test() is not. Therefore a is initialized before t even if both are static final.

这篇关于Java静态final字段初始化顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆