preface
- Class loaders are used to load classes.
- Array classes are created by the JVM at run time.
Who loads ExtensionClassLoader and AppClassLoader?
- ExtensionClassLoader and AppClassLoader are implemented by Java code, which means they are also classes that need to be loaded.
- This is loaded by the BootstrapClassLoader, but who loads the BootstrapClassLoader?
- BootstrapClassLoader is implemented in C/C++. It is associated with the VM and starts when the VM starts.
Start the class loader
- The Bootstrap ClassLoader built into the JVM loads java.lang.ClassLoader and other Java platform classes. When the JVM starts, a special machine code is run that loads both the extension ClassLoader and the system ClassLoader.
- The launcher class loader is not a Java class, and all the other loaders are Java classes
- The launch class loader is a platform-specific machine instruction that is responsible for starting the entire loading process. All class loaders (except the boot class loaders) are implemented as Java classes. However, there must always be a component to load the first Java class loader so that the loading process can proceed smoothly, and loading the first pure Java class loader is the responsibility of the launcher.
- The launcher class loader is also responsible for loading the basic components needed for the JRE to run properly, including classes in the java.util and java.lang packages, and so on.
validation
-
First, ExtensionClassLoader and AppClassLoader define inner classes in the Launcher class.
-
When the Launcher class is loaded, the two classloaders are loaded. If you look at the Launcher class, you know who is loading ExtensionClassLoader and AppClassLoader
-
code
public class BootStrapTest { public static void main(String[] args) { System.out.println(Launcher.class.getClassLoader()); }}Copy the code
-
The results of
-
I mentioned that NULL represents BootStrapClassLoader.
-
The Launcher class has the code about how to create ExtensionClassLoader and AppClassLoader, but Oracle company is not open source, need to use OpenJDK, later have time to read JDK source code.
Class.forName
JDK source code
- This method is usually used when connecting to the database to load the driver. The parameter is passed as a string about the driver name. In fact, it has three parameters.
- translation
- Returns the Class object associated with the Class or interface with the given string name using the given classloader. Given the fully qualified name of the class or interface (the same format returned by getName), this method attempts to locate, load, and link the class or interface. The specified class loader is used to load a class or interface. If the loader argument is empty, the class is loaded through the (BootstrapClassLoader) bootloader. The class is initialized only if the initialize parameter is true and the class has not been initialized before.
- If name represents a primitive data type or void, an attempt is made to locate the user-defined class in an unnamed package named Name. Therefore, this method cannot be used to get any Class object representing a primitive data type or void.
- If name represents an array class, the component type of the array class is loaded but not initialized. Arrays, after all, are created by the VM at runtime
- Parameters:
- Name – Fully qualified name of the required class.
- Initialize – If true, the class will be initialized.
- Loader – the class loader from which classes must be loaded.
- The return value:
- A class object that represents the required class
Digress (specifying the system classloader)
The System properties
public class BootStrapTest {
public static void main(String[] args) {
//System.out.println(Launcher.class.getClassLoader());
System.out.println(System.getProperty ("sun.boot.class.path"));//BootStrapClassLoader Default loading path
System.out.println(System.getProperty("java.ext.dirs"));//ExtensionClassLoader default loading path
System.out.println(System.getProperty("java.class.path"));//AppClassLoader Default loading path
System.out.println( "-- -- -- -- -- -- -- --");
System.out.println(System.getProperty ("java.system.class.loader"));// System class loader
System.out.println(ClassLoader.getSystemClassLoader()) ;// Load the system class loader}}Copy the code
- The results of
-
Look at this. GetSystemClassLoader () method of the source code
-
Returns the system class loader used for the delegate. This is the default delegate parent for a new ClassLoader instance and is typically used to launch the application’s ClassLoader.
This method is first invoked early in the sequence at runtime, where it creates the system classloader and sets it up as the context classloader that calls Thread.
- The default system class loader is an implementation-dependent instance of this class.
- If the system property “java.system.class.loader” is defined when this method is first called, the value of that property is treated as the name of the class to be returned as the system classloader. The class is loaded using the default system ClassLoader and must define a public constructor that takes a ClassLoader parameter that acts as the delegate parent. You then use this constructor to create an instance with the default system classloader as an argument. The generated class loader is defined as the system class loader.
- If the security manager exists and the caller’s class loader is not empty and the caller’s class loader is different or an ancestor of the system class loader, This method calls the security manager’s checkPermission method to verify access to the system classloader with RuntimePermission(“getClassLoader”) permission. If not, a SecurityException is thrown.
- The return value:
- System classloader for delegates, or null if not present
Throws:
- SecurityException – If the security manager exists and its checkPermission method does not allow access to the system classloader.
- IllegalStateException – if called recursively during the construction of the classloader specified by the “java.system.class.loader” property.
- Error – If the system property “java.system.class.loader” is defined but the named class cannot be loaded, the provider class does not define the required constructor, or the constructor throws an exception when called. The root cause of the error can be retrieved using the throwable.getCause () method.
In other words?
- You can replace the system class loader by yourself.
- You must also define a public constructor that takes an argument of type ClassLoader
public UserClassLoader(ClassLoader parent) {// Custom class constructor super(parent);// Explicitly define the parent loader of the class loader } Copy the code
Custom class loaders come first.
- Just set the system property java.system.class.loader.
code
public class BootStrapTest {
public static void main(String[] args) {
//System.out.println(Launcher.class.getClassLoader());
System.out.println(System.getProperty ("sun.boot.class.path"));//BootStrapClassLoader Default loading path
System.out.println(System.getProperty("java.ext.dirs"));//ExtensionClassLoader default loading path
System.out.println(System.getProperty("java.class.path"));//AppClassLoader Default loading path
System.out.println( "-- -- -- -- -- -- -- --");
System.out.println(System.getProperty("java.system.class.loader"));// System class loader
//System.out.println(ClassLoader.getSystemClassLoader()) ; // Load the system class loader
System.out.println(ClassLoader.getSystemClassLoader().getClass()) ;// Load the system class loader}}Copy the code
- You need to use -d < name >=< Value > to set system properties
- The command for my custom class loader is as follows:
java -D"java.system.class.loader"="com.jvmstudy.classloading.UserClassLoader" com.jvmstudy.classloading.BootStrapTest Copy the code
- The results of