1

Given the following code-snippet I get the output "B" and "error":

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. Also if I access the field B.c directly without reflection before doing the reflection stuff the problem does not occur. Why is that so and how can I fix it?

1
  • I would refactor the code to remove the circular dependency between the two classes. This would almost certainly fix your problem as well. Commented Feb 25, 2015 at 11:38

1 Answer 1

3

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 B.c to a static field of A, but this field is still null.

If the class B is initialized first, it has a dependency in class A, the class A is initialized and A.c is set to a new B instance and B.c is initialized correctly.

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.

Sign up to request clarification or add additional context in comments.

2 Comments

Close. However, the problem is not with the order in which classes are loaded. It is in the order that they are initialized. Or more precisely, the order in which the respective classes' static initialization occurs.
@StephenC Thanks for your comment. That was my point. I reworded my answer to try to be more precise with the terms.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.