JVM -- 07 -- forName()和loadClass()的区别

类的加载方式可分为隐式加载和显示加载两种

  • 隐式加载:new

    • 对于隐式加载而言,当程序在运行过程中,遇到通过 new 方式来生成对象时,会隐式调用类加载器,加载对应的类到虚拟机中
  • 显示加载:forName()、loadClass()

    • 对于现实加载而言,当我们获取到 Class 对象之后,需要调用 Class 对象的 newInstance() 方法来生成对象实例

forName() 和 loadClass() 同为显示加载,那么他们之间又有什么区别呢,让我们一起来看看


一、区别

  • loadClass()

    • loadClass() 是 ClassLoader 类的实例方法

    • 通过 loadClass() 方法得到的 Class 对象只完成了类加载过程的第一步 - 加载阶段

  • forName()

    • forName() 是 Class 类的静态方法

    • 通过 forName() 方法得到的 Class 对象已经完成了初始化,即已经完成了类加载的全部过程


二、验证

public class Robot {

    static {
        System.out.println("Hello Robot");
    }
}

public class LoadDifference {

    public static void main(String[] args) throws Exception {
        ClassLoader classLoader = Robot.class.getClassLoader();
        classLoader.loadClass("com.xj.classloader.Robot"); // 无打印

        Class.forName("com.xj.classloader.Robot"); // Hello Robot
    }
}
  • 如上所示,loadClass() 方法没有执行静态代码块,而 forName() 方法执行了静态代码块

  • 由此可见,通过 forName() 方法得到 Class 对象已经完成了初始化


三、举例

  • loadClass()

    • 在 Spring IOC 容器中,在资源加载器获取要读入的资源时 (即读取一些 bean 的配置文件),如果是以 CLASSPATH 的方式来加载,就需要用到 loadClass() 方法,之所以这样做,是和 Spring 的 lazy loading (延迟加载) 有关,IOC 容器为了加快初始化速度,因此大量使用了延迟加载技术

    • 使用 loadClass() 方法不需要执行类中的初始化代码,从而加快加载速度,把类的初始化工作留到实际使用这个类的时候再去做

  • forName()

    • 可用于加载 mysql 驱动 (Class.forName(“com.mysql.jdbc.Driver”))
      JVM -- 07 -- forName()和loadClass()的区别_第1张图片

你可能感兴趣的:(jvm)