Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When does the JVM load classes?

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?

like image 809
Garrett Hall Avatar asked Sep 26 '11 20:09

Garrett Hall


People also ask

How does JVM load classes?

In order to actually load a class, the JVM uses Classloader objects. Every already loaded class contains a reference to its class loader, and that class loader is used to load all the classes referenced from that class.

Which classes are loaded when JVM starts?

Initially when a JVM starts up, nothing is loaded into it. The class file of the program being executed is loaded first and then other classes and interfaces are loaded as they get referenced in the bytecode being executed.

Does JVM load all classes on startup?

Therefore, the JVM doesn't need to know about the underlying files or file systems in order to run Java programs thanks to class loaders. Furthermore, these Java classes aren't loaded into memory all at once, but rather when they're required by an application. This is where class loaders come into the picture.

What is class loading time in Java?

Java ClassLoader is used to load the classes at run time. In other words, JVM performs the linking process at runtime. Classes are loaded into the JVM according to need. If a loaded class depends on another class, that class is loaded as well. When we request to load a class, it delegates the class to its parent.


2 Answers

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.

like image 169
Matthew Farwell Avatar answered Oct 23 '22 00:10

Matthew Farwell


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.

like image 44
Sean Owen Avatar answered Oct 23 '22 01:10

Sean Owen