preface

When I was reading some articles about Java agents today, I thought about reflection through dynamic proxies, and then I thought about an interview question I was asked: what’s the difference between class. forName and ClassLoader? “, although he answered at that time, but the answer is not specific, today is free to do a reorganization.

In Java, class.forname () and ClassLoader load classes. We also know that class.forname loads static code blocks, but ClassLoader does not load static code blocks.

We can also deduce from the above that the ClassLoader follows the parent delegate model and eventually calls the ClassLoader to load it. Its function is to get the binary byte stream of a class by its class name and then export that byte to the JVM. We can look at the source of class.forname:

@CallerSensitive
public staticClass<? > forName(String className)throwsClassNotFoundException { Class<? > caller = Reflection.getCallerClass();return forName0(className, true, ClassLoader.getClassLoader(caller), caller);
}
Copy the code

You can see in the source code above that the result is a call to the forName0 method, which takes four arguments:

  • The first argument: the class name
  • The second argument: whether to initialize the class. If set to true, static code blocks in the class are executed
  • Third argument: The third argument is to set the class loader

So we can use class.forname (String name, Boolean initialize,ClassLoader) to set our own initialization and ClassLoader.

For classloaders, there are three types of Classloaders in Java:

  • BootstrapClassLoader
  • ExtClassLoader
  • AppClassLoader

In the ClassLoader source code, it is mainly these three kinds of loaders to load the class through the path of the class to generate binary bytes to be exported to the JVM.

/* * The class loader used for loading installed extensions. */
    static class ExtClassLoader extends URLClassLoader {
 
        static {
            ClassLoader.registerAsParallelCapable();
        }
 
        /** * create an ExtClassLoader. The ExtClassLoader is created * within a context that limits which files it can read */
        public static ExtClassLoader getExtClassLoader(a) throws IOException
        {
            final File[] dirs = getExtDirs();
 
            try {
                // Prior implementations of this doPrivileged() block supplied
                // aa synthesized ACC via a call to the private method
                // ExtClassLoader.getContext().
 
                return AccessController.doPrivileged(
                    new PrivilegedExceptionAction<ExtClassLoader>() {
                        public ExtClassLoader run(a) throws IOException {
                            int len = dirs.length;
                            for (int i = 0; i < len; i++) {
                                MetaIndex.registerDirectory(dirs[i]);
                            }
                            return newExtClassLoader(dirs); }}); }catch (java.security.PrivilegedActionException e) {
                throw(IOException) e.getException(); }}private static File[] getExtDirs() {
            String s = System.getProperty("java.ext.dirs");
            File[] dirs;
            if(s ! =null) {
                StringTokenizer st =
                    new StringTokenizer(s, File.pathSeparator);
                int count = st.countTokens();
                dirs = new File[count];
                for (int i = 0; i < count; i++) {
                    dirs[i] = newFile(st.nextToken()); }}else {
                dirs = new File[0];
            }
            returndirs; }... }Copy the code

Where is class. forName or ClassLoader used?

  • When making JDBC connections, we usually do this using class.forname.
  • The IOC in Spring uses the ClassLoader.

Class. ForName and ClassLoader.