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

  1. When a classloader receives a classloading request, it first delegates the request to the parent classloader.
  2. If the parent class still has a superclass attached to it, delegate up to the top levelBooststap ClassLoaderSo far.
  3. 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 loadClassNotFoundExceptionThe 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