美文网首页
类加载 Class.forName() 和 loadClass(

类加载 Class.forName() 和 loadClass(

作者: 牧呈 | 来源:发表于2018-03-23 19:39 被阅读0次

    1. Class.forName() 和 loadClass() 加载类的区别

    public class Test {
            public static class Hello {
                static {
                       System.out.println("hello");
                }
           }
           public static void main(String[] args) {
                 ClassLoader classLoader = ClassLoader.getSystemClassLoader();
                 String className = Test.class.getName() + "$Hello";
                 try {
                      //Class<?> cls = classLoader.loadClass(className);
                      Class.forName(className);
                      System.out.println(classLoader);
                 } catch (ClassNotFoundException e) {
                     e.printStackTrace();
                }
          }
    }
    

    区别: loadClass() 方法加载类不会对其进行初始化,而通过Class.forName() 方法加载类会对其进行初始化。

    2. loadClass() 方法(删除了一些代码):

    protected Class<?> loadClass(String name, boolean resolve)
            throws ClassNotFoundException
        {
            synchronized (getClassLoadingLock(name)) {
                // 首先,检查类是否已经被加载了           
                Class<?> c = findLoadedClass(name);
                if (c == null) {
                    // 没被加载,先委派父 ClassLoader 或 Bootstrap ClassLoader 去加载
                    try {
                        if (parent != null) {
                             // 委派父 ClassLoader,resolve 参数固定为 false 
                            c = parent.loadClass(name, false);
                        } else {
                            c = findBootstrapClassOrNull(name);
                        }
                    } catch (ClassNotFoundException e) {
                            // 没找到,捕获异常,以便尝试自己价值   
                    }
    
                    if (c == null) {
                            // 自己去加载,findClass 才是当前 ClassLoader 的真正加载方法
                        c = findClass(name);
                    }
                }
                if (resolve) {
                    // 链接,执行 static 语句块
                    resolveClass(c);
                }
                return c;
            }
        }
    

    参数 resolve 类似 Class.forName 中的参数 initialize,可以看出,其默认值为 false,即使通过自定义 ClassLoader 重写 loadClass,设置 resolve 为 true,它调用父 ClassLoader 的时候,传递的也是固定的 false。

    相关文章

      网友评论

          本文标题:类加载 Class.forName() 和 loadClass(

          本文链接:https://www.haomeiwen.com/subject/hlzxcftx.html