The class loader first checks to see if the Class Object for that type is loaded. If not, the default class loader finds the .class file with that name (an add-on class loader might, for example, look for the bytecodes in a database instead).
- Each class object is loaded only when it's needed.
- The static initialization is performed upon class loading.
forName
public static Class<?> forName(String className)
throws ClassNotFoundException
Returns the Class
object associated with the class or interface with the given string name. Invoking this method is equivalent to:
Class.forName(className, true, currentLoader)
where currentLoader
denotes the defining class loader of the current class.
For example, the following code fragment returns the runtime Class
descriptor for the class named java.lang.Thread
:
Class t = Class.forName("java.lang.Thread")
A call to forName("X")
causes the class named X
to be initialized.
Parameters:
className
- the fully qualified name of the desired class.
Returns:
the Class
object for the class with the specified name.
Throws:
LinkageError
- if the linkage fails
ExceptionInInitializerError
- if the initialization provoked by this method fails
ClassNotFoundException
- if the class cannot be located
For example
// typeinfo/SweetShop.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// Examination of the way the class loader works
class Cookie {
static {
System.out.println("Loading Cookie");
}
}
class Gum {
static {
System.out.println("Loading Gum");
}
}
class Candy {
static {
System.out.println("Loading Candy");
}
}
public class SweetShop {
public static void main(String[] args) {
System.out.println("inside main");
new Candy(); // static method class
System.out.println("After creating Candy");
try {
Class.forName("Gum"); // [1]
} catch (ClassNotFoundException e) {
System.out.println("Couldn't find Gum");
}
System.out.println("After Class.forName(\"Gum\")");
new Cookie();
System.out.println("After creating Cookie");
}
}
/*
execute
$ ./gradlew :typeinfo:SweetShop
Output:
inside main
Loading Candy
After creating Candy
Loading Gum
After Class.forName("Gum")
Loading Cookie
After creating Cookie
*/
when run above example in Eclipse, [1] will throw ClassNotFoundException
/** * Returns the {@code Class} object associated with the class or * interface with the given string name. Invoking this method is * equivalent to: * * <blockquote> * {@code Class.forName(className, true, currentLoader)} * </blockquote> * * where {@code currentLoader} denotes the defining class loader of * the current class. * * <p> For example, the following code fragment returns the * runtime {@code Class} descriptor for the class named * {@code java.lang.Thread}: * * <blockquote> * {@code Class t = Class.forName("java.lang.Thread")} * </blockquote> * <p> * A call to {@code forName("X")} causes the class named * {@code X} to be initialized. * * @param className the fully qualified name of the desired class. * @return the {@code Class} object for the class with the * specified name. * @exception LinkageError if the linkage fails * @exception ExceptionInInitializerError if the initialization provoked * by this method fails * @exception ClassNotFoundException if the class cannot be located */ @CallerSensitive public static Class<?> forName(String className) throws ClassNotFoundException { return forName0(className, true, ClassLoader.getClassLoader(Reflection.getCallerClass())); }
Basically, the @CallerSensitive
annotation is used by the JVM
The JVM will track this annotation and, optionally, enforce the invariant that the
sun.reflect.Reflection.getCallerClass
method can only report the caller of a method when that method is marked with this annotation.
references:
1. On Java 8 - Bruce Eckel
2. https://github.com/wangbingfeng/OnJava8-Examples/blob/master/typeinfo/SweetShop.java
3. https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#forName-java.lang.String-
5. http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/classes/java/lang/Class.java