When does the JVM load classes?

13,419

Solution 1

A class is loaded only when you require information about that class.

public class SomethingCaller {
    public static Something something = null; // (1) does not cause class loading
    public static Class<?> somethingClass = Something.class; // (2) causes class loading

    public void doSomething() {
        new Something(); // (3) causes class loading
    }
}

The lines (2) & (3) would cause the class to be loaded. The Something.class object contains information (line (2)) which could only come from the class definition, so you need to load the class. The call to the constructor (3) obviously requires the class definition. Similarly for any other method on the class.

However, line (1) doesn't cause the class to be loaded, because you don't actually need any information, it's just a reference to an object.

EDIT: In your changed question, you ask whether referring to Something.class loads the class. Yes it does. It does not load the class until main() is executed though. Using the following code:

public class SomethingTest {
    public static void main(String[] args) {
        new SomethingCaller();
    }
}

public class SomethingCaller {
    public void doSomething() {
        Class<?> somethingClass = Something.class;
    }
}

public class Something {}

This code does not cause the Something.class to be loaded. However, if I call doSomething(), the class is loaded. To test this, create the above classes, compile them and delete the Something.class file. The above code does not crash with a ClassNotFoundException.

Solution 2

Yes, that will cause the class to load when the class containing the File.class reference is loaded. The only way to not do this is to reference a class by reflection. Then you can control when it's loaded.

Share:
13,419
Garrett Hall
Author by

Garrett Hall

Updated on June 27, 2022

Comments

  • Garrett Hall
    Garrett Hall almost 2 years

    Assume I have the following class:

    class Caller {
      public void createSomething() {
        new Something();
      }
    }
    

    Would executing this line:

    static void main() {
       Class<?> clazz = Caller.class;
    }
    

    cause the JVM to load the class Something or is the class loading deferred until the method createSomething() is called?

  • parsifal
    parsifal over 12 years
    I take it that you've never written a custom classloader?
  • Garrett Hall
    Garrett Hall over 12 years
    So when the program executes a line containing File.class then all the class referenced inside the File class are also loaded?
  • Garrett Hall
    Garrett Hall over 12 years
    But would referencing SomethingCaller.class cause the class Something to be loaded (ignoring the static fields). (Please see updated question for details)
  • Sean Owen
    Sean Owen over 12 years
    Updated to say: it's not loaded until used, so in general, you should just not worry about what you're worrying about in this question and leave it to Java. See comment on other question for an interesting detail.
  • Sean Owen
    Sean Owen over 12 years
    Strangely, I thought the same, and then I tested this -- just referring to Something.class doesn't seem to load it! Instantiating it or something does of course.
  • Matthew Farwell
    Matthew Farwell over 12 years
    Just to clarify, the class is not loaded until the line that contains the Something.class is executed.
  • Garrett Hall
    Garrett Hall over 12 years
    Okay thanks for the detailed responses, that is what I suspected.
  • davidbak
    davidbak over 8 years
    I don't think this is correct anymore for (2) - Java 8. I can assign Class<?> k = Foo.class; and get a Class instance that has the type name but it hasn't executed any static blocks in the class.
  • arxakoulini
    arxakoulini about 6 years
    @davidbak Your line of code will cause the class to be loaded but not to be initialized, as this line of code does not fall into the rules of when static initialization will happen.
  • davidbak
    davidbak about 6 years
    @NikiforosArchakis - thanks for the clarification! I'll now want to read about the "lifecycle of a Java class" ...