This is the 28th day of my participation in the November Gwen Challenge. Check out the event details: The last Gwen Challenge 2021
Java-ClassLoader
There are two main types of class loaders in Java: system class loaders and custom class loaders.
loader | The name of the class | introduce |
---|---|---|
Booststap ClassLoader | C/C++ is written without Java classes | It is written in C/C++. It is mainly used to load the JDK core code library. Such as java.lang, java.uti and other system classes |
Extensions ClassLoader | ExtClassLoader | Used to load Java extension classes that provide additional functionality beyond the system classes |
Application ClassLoader | AppClassLoader | Can be called System ClassLoader for loading directory class libraries |
Custom ClassLoader | Inherit this | A custom loader is a custom function ClassLoader implemented by inheriting ClassLoader |
ClassLoader inheritance relationship
The ClassLoader inheritance relationship is shown as follows. Classes written with main() in Java inherit from AppClassLoader. The parent loader of AppClassLoader is ExtClassLoader. The parent loader of ExtClassLoader is Booststap ClassLoader, but it is written in C/C++ without Java classes.
classDiagram ClassLoader <|-- SecureClassLoader SecureClassLoader <|-- URLClassLoader URLClassLoader <|-- ExtClassLoader URLClassLoader <|-- AppClassLoader
Loading process – Parent delegate mode
Class loaders find classes in parental delegation mode, which determines whether the class is already loaded: If it is not loaded, it will entrust the parent loader to search for it and carry out recursive operations until it reaches the top Booststap ClassLoader. If it finds it, it will return directly. If it does not find it, it will search down successively.
Specific principles and steps
- When a classloader receives a classloading request, it first delegates the request to the parent classloader.
- If the parent class still has a superclass attached to it, delegate up to the top level
Booststap ClassLoader
So far. - If the parent class loader can load, the result is returned. If the parent class fails to load, the subclass tries to load, and the subclass fails to load
ClassNotFoundException
The exception.
Android-ClassLoader
Java ClassLoader can load JAR packages and Class files, while Android does not support loading dex files in Android virtual machines. Therefore, Android ClassLoader cannot communicate with Java ClassLoader. The Android ClassLoader is similar to the Java ClassLoader. It is also a system ClassLoader and a custom ClassLoader.
loader | The name of the class | introduce |
---|---|---|
BootClassLoader | BootClassLoader | BootClassLoader is the loader used by Android system to load commonly used classes. The difference is that it is not implemented by C/C++ code, but Java code. |
DexClassLoader | DexClassLoader | Used to load dex files and compressed packages containing dex files |
PathClassLoader | PathClassLoader | The PathClassLoader is used to load system classes and application classes |
ClassLoader inheritance relationship
classDiagram
ClassLoader <|-- BootClassLoader
ClassLoader <|-- BaseDexClassLoader
ClassLoader <|-- SecureClassLoader
SecureClassLoader <|-- URLClassLoader
BaseDexClassLoader <|-- InMemoryDexClassLoader
BaseDexClassLoader <|-- PathClassLoader
BaseDexClassLoader <|-- DexClassLoader
The loading process
The Android ClassLoader is also in parental delegation mode. ClassLoader uses the loadClass method to load the class. LoadClass calls the findClass method and then calls the findClass method of DexPathList. Iterate through all the loaded dex files, and then call loadClassBinaryName method to load the classes to be loaded; LoadClassBinaryName calls the Native method defineClass to load the class. Finally, the ClassLoader creation and loading process is complete.
// #ClassLoader.loadClass
publicClass<? > loadClass(String className)throws ClassNotFoundException {
return loadClass(className, false);
}
protectedClass<? > loadClass(String className,boolean resolve) throwsClassNotFoundException { Class<? > clazz = findLoadedClass(className);if (clazz == null) {
ClassNotFoundException suppressed = null;
try {
clazz = parent.loadClass(className, false);
} catch (ClassNotFoundException e) {
suppressed = e;
}
if (clazz == null) {
try {
clazz = findClass(className);
} catch (ClassNotFoundException e) {
e.addSuppressed(suppressed);
throwe; }}}return clazz;
}
// #ClassLoader.findClass
@Override
protectedClass<? > findClass(String name)throws ClassNotFoundException {
Class clazz = pathList.findClass(name);
if (clazz == null) {
throw new ClassNotFoundException(name);
}
return clazz;
}
// #DexPathList.findClass
public Class findClass(String name) {
for (Element element : dexElements) {
DexFile dex = element.dexFile;
if(dex ! =null) {
Class clazz = dex.loadClassBinaryName(name, definingContext);
if(clazz ! =null) {
returnclazz; }}}return null;
}
// #DexPathList.loadClassBinaryName
public Class loadClassBinaryName(String name, ClassLoader loader) {
return defineClass(name, loader, mCookie);
}
private native static Class defineClass(String name, ClassLoader loader, int cookie);
Copy the code
reference
- # Java class loading mechanism parent delegate pattern