简体   繁体   English

使用Reflection时,Java中的奇怪静态初始化

[英]Weird static initialization in Java when using Reflection

Given the following code-snippet I get the output "B" and "error": 给定以下代码片段,我得到输出“B”和“错误”:

public class Test {

    private static class A {
        static final B c = new B();
    }

    private static class B extends A {
        static final B c = A.c;
    }

    public static void main(String[] args) throws Exception {
        for(Class<?> cls : Test.class.getDeclaredClasses()) {
            if(cls.getDeclaredFields()[0].get(null) == null) {
                System.out.println(cls.getSimpleName());
            }
        }
        if(B.class.getDeclaredField("c").get(null) == null) {
            System.out.println("error");
        }
    }

}

But it gets even more bizarre. 但它变得更奇怪了。 If I comment-out the for-loop I get no output - so no error. 如果我注释掉for循环,我得不到输出 - 所以没有错误。 Also if I access the field Bc directly without reflection before doing the reflection stuff the problem does not occur. 此外,如果我在进行反射之前直接访问字段Bc而没有反射,则不会发生问题。 Why is that so and how can I fix it? 为什么会这样,我该如何解决?

The problem is not related with reflection, is related with the order in which classes are initialized. 问题与反射无关,与初始化类的顺序有关。

If class A is initialized first, it has a dependency in class B, class B tries to initialize Bc to a static field of A, but this field is still null. 如果首先初始化类A,它在类B中具有依赖性,则类B尝试将Bc初始化为静态字段A,但此字段仍为空。

If the class B is initialized first, it has a dependency in class A, the class A is initialized and Ac is set to a new B instance and Bc is initialized correctly. 如果首先初始化类B,它在类A中具有依赖性,则初始化类A并且将Ac设置为新的B实例并且正确地初始化Bc。

To make an example more simple, this code shows the problem simplified: 为了使示例更简单,此代码显示了简化的问题:

public static void main(String[] args) throws Exception {
    System.out.println(A.c);
    System.out.println(B.c);
}

Output: 输出:

Test$B@f72617
null

And this other example: 另一个例子是:

public static void main(String[] args) throws Exception {
    System.out.println(B.c);
    System.out.println(A.c);
}

Output: 输出:

Test$B@f72617
Test$B@f72617

To solve the problem you could change your design to remove the circular dependency or make sure the classes are initialized in the right order. 要解决此问题,您可以更改设计以删除循环依赖项或确保按正确的顺序初始化类。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM