java · 2024-09-04 0

Class.forName() 和 ClassLoader.loadClass() 的区别

1.java 类

public class Dog {

    static {
        System.out.println("- - - Dog static - - -");
    }

    public Dog() {
        System.out.println("- - - Dog() - - -");
    }
}

2.测试类

/*
    结果:
    - - - Class.forName - - -
    - - - Dog static - - -
    - - - clazz.newInstance - - -
    - - - Dog() - - -
 */
@Test
public void testClassForName1() throws Exception {
    ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
    System.out.println("- - - Class.forName - - -");
    // 第一次 Class.forName 会调用 ClassLoader.loadClass(name) 方法
    Class clazz1 = Class.forName("com.example.dog.Dog", true, classLoader);
    // 第二次 Class.forName 不会调用 ClassLoader.loadClass(name) 方法
    Class clazz2 = Class.forName("com.example.dog.Dog", true, classLoader);
    System.out.println("- - - clazz.newInstance - - -");
    Object obj1 = clazz1.newInstance();
}

/*
    结果:
    - - - Class.forName - - -
    - - - clazz.newInstance - - -
    - - - Dog static - - -
    - - - Dog() - - -
 */
@Test
public void testClassForName2() throws Exception {
    ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
    System.out.println("- - - Class.forName - - -");
    // 第一次 Class.forName 会调用 ClassLoader.loadClass(name) 方法
    Class clazz1 = Class.forName("com.example.dog.Dog", false, classLoader);
    // 第二次 Class.forName 不会调用 ClassLoader.loadClass(name) 方法
    Class clazz2 = Class.forName("com.example.dog.Dog", false, classLoader);
    System.out.println("- - - clazz.newInstance - - -");
    Object obj1 = clazz1.newInstance();
}

/*
    结果:
    - - -  classLoader.loadClass - - -
    - - - clazz.newInstance - - -
    - - - Dog static - - -
    - - - Dog() - - -
 */
@Test
public void testClassLoader() throws Exception {
    ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
    System.out.println("- - -  classLoader.loadClass - - -");
    Class clazz1 = classLoader.loadClass("com.example.dog.Dog");;
    Class clazz2 = classLoader.loadClass("com.example.dog.Dog");;
    System.out.println("- - - clazz.newInstance - - -");
    Object obj1 = clazz1.newInstance();
}

3.区别

  1. Class.forName() 加载的类会被初始化,类中的静态成员变量会被初始化,静态代码块会被执行。
  2. 通过 ClassLoader.loadClass 加载的类不进行解析操作,不进行解析操作就意味着初始化也不会进行,那么其类的静态参数就不会初始化,静态代码块也不会被执行。