I cannot easily find it in JLS/JVMSpec, nor in SO. I’m sure it must’ve been asked…
So, what does “new” do actually? Suppose we instantiate a class B in A:
class A {
// ...
new B();
// ...
}
Is this equivalent to
class A {
// ...
A.class.getClassLoader().loadClass("B's canonical name").newInstance();
// ...
}
?
Does it, or does it not work like that in every environment?
I’d be grateful if you can point me to the appropriate chapter in JLS/JVMSpec. Thanks!
Edit: surely we can’t call B.class.getCanonicalName() in loadClass() call, since B’s not loaded yet. JVM has to resolve the name based on the import statement.
No, not always.
Class loading is performed only once for a given namespace, unless the
Classin question has been previously unloaded. Therefore, the equivalent expressionA.class.getClassLoader().loadClass("B's canonical name")will be executed only once in most scenarios. In other words, if you have two expressions –new A(), theloadClasswill be performed only once.Invocation of a constructor is treated as a method invocation by the JVM, but this requires the cooperation of a Java compiler. The JVM and the compiler have to adhere to section 3.9 of the Java Virtual Machine Specification, which states:
This section assumes that the
Classobject pertaining to the class in question is available to the current thread. Once theClassobject is available, the method<init>corresponding to the constructor with the right set of arguments, will be invoked.The question of which classloader will be used to load the class, if not already loaded, is a bit different, and has nothing to do with the new keyword. It depends on how one class references another i.e. does a symbolic reference need to be resolved in the runtime constant pool? The behavior in this context is defined in Section 5.3 of the Java Virtual Machine Specification:
Note the sentence –
If D was defined by a user-defined class loader, then that same user-defined class loader initiates loading of Cin the above quote. In the context of the expressionnew A(), the classloader that loaded the enclosing class will be responsible for loadingAin accordance with the VM Spec; this is of course, assuming that the enclosing class is not loaded by the bootstrap classloader.