1

Java initializes outer class static field when that class is interacted with, but does not initialize nested static class field.

So I have read the nested class documentation: https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html and I think it comes down to this line here:

In effect, a static nested class is behaviorally a top-level class that has been nested in another top-level class for packaging convenience.

If my understanding is correct that means that java views my two classes below as separate entities;

public class OutterClass {

    private static final OutterClass outterField = new OutterClass("outterField");

    private OutterClass(String string) {
        System.out.println(string + " has been initialised");
    }

    private static class InnerClass {
        private static final OutterClass innerField = new OutterClass("innerField");
    }

    public static void foo() {}
}

Meaning that when I interact with the OuterClass by calling the Outer.foo(), java will initialize my static field as it is part of the OuterClass. But since it views the InnerClass as a separate top level class, InnerClass's fields don't get initialized.

1) Is my understanding correct?

2) Has this got anything to do with the JIT compiler or the class loader? Is the InnerClass loaded when the OuterClass is loaded?

Thanks

2
  • 1
    1) yes (inner class is compiled and a separate class-file is created, a different class eventually with some synthetic methods to allow access to private members from outer class); 2) no or no, no (it is, for VM, just a normal separate class - the compiler did all the magic) Commented Sep 3, 2019 at 4:37
  • Could you add this as an answer so that I can accept it. I checked my class files and you are right, it did build two separate class files for the InnerClass and OuterClass. It makes a lot more sense now why the InnerClass.innerField is not initialized as it is physically in a separate file. Commented Sep 3, 2019 at 5:03

1 Answer 1

1

1) Is my understanding correct?

Basically yes. Consider what happens with your static member outerField :

public class OutterClass {

    private static final OutterClass outterField = new OutterClass("outterField");

Theoretically, it's possible that the JVM could create that static final object when the program starts running, or when the class is loaded, but it doesn't. Instead, it'll only initialise it when needed - basically :

  • Instance of class is created, or
  • One of the Class's static fields or methods is accessed

(see https://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.4.1 )

So also with the static inner class. As you say, the JVM regards it as a top level inner class, so will only initialise its members when it also is needed.

2) Has this got anything to do with the JIT compiler or the class loader?

No and no. Initialisation of static members does not take place at class load time, but later (as we said, when the class is accessed). This is not a matter of compiler optimisation, but explicitly specified behaviour. After all, when you load a possibly-large class library, you would not want your JVM to consume memory or time initialising all the static members of classes that your program never touches; only-on-demand is a much better approach.

Is the InnerClass loaded when the OuterClass is loaded?

Yes (but not initialised then)

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

1 Comment

Ah, good call, and it looks like the JLS leaves it open for JVM implementations to resolve (so loading) classes "eager" or "late" (docs.oracle.com/javase/specs/jvms/se7/html/jvms-5.html#jvms-5.4 ) For example, OutterClass, could well not trigger a load of InnerClass, especially since it is an unusual case that InnerClass is never used. If OutterClass had methods that returned an InnerClass, that could well trigger a class load to resolve them.

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.