探讨Class.forName与ClassLoader.loadClass与new Object

探讨Class.forName与ClassLoader.loadClass与new Object

实例展示

TestObject对象

public class TestObject {

    static {
        System.out.println("我已经成功初始化。");
    }

}

TestDriver测试

public class TestDriver {

    public static void main(String[] args) {
        try {
            //1. 使用Class.forName加载
            //Class.forName(TestObject.class.getName());


            //2. 使用loader.load加载
            ClassLoader loader=TestDriver.class.getClassLoader();
            loader.loadClass(TestObject.class.getName());

            //3. 使用new Object
            //TestObject object=new TestObject();

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

}

测试结果

1.使用Class.forName加载
输出:我已经成功初始化。

2.使用loader.load加载
没有任何输出

3.使用new Object
输出:我已经成功初始化。

理论谈论

我们知道Java在加载的过程将经过这么几个步骤。

从上面的结果,我们可以看出,其实Class.forName与new Object的方法已经完成了类的初始化,但是ClassLoader.loadClass只是完成了类的加载。之所以要加载类是因为JVM并不是在项目运行时就把所有的类文件加载到JVM,而是当类需要的的时候,才去加载。
加载就是通过类的全限定名获取二进制字节流,将二进制字节流转成方法区中运行的数据结构,在内存中生成Java.lang.class对象。

Class.forName(className)法实际上调用的方法是Class.forName0(className, true, ClassLoader.getClassLoader(caller), caller),第二个参数boolean代表类是否需要被初始化。

ClassLoader.loadClass(className)方法实际上调用的方法是ClassLoader.loadClass(name, false),第二个参数boolean代表的是类是否进行链接。

从上面可以看出,ClassLoader.loadClass(className)默认是不链接的,意味着,静态方法将无法被执行。

扩展

我们第一次认识Class.forName,可能是在写数据库连接的时候。那时候,我就按照教程写,很轻松就拿到了连接。
现在,我们来分析一下JDBC驱动装载过程:
当我们写
Class.forName(“com.MySQL.jdbc.Driver”);
com.MySQL.jdbc.Driver将被初始化,这时候,调用了com.MySQL.jdbc.Driver静态初始化块

static {
    try {
        DriverManager.registerDriver(new Driver());
    } catch (SQLException var1) {
        throw new RuntimeException("Can\'t register driver!");
    }
}

向DriverManager注册了这个驱动。

public static synchronized void registerDriver(java.sql.Driver driver,
            DriverAction da)
        throws SQLException {

        /* Register the driver if it has not already been added to our list */
        if(driver != null) {
            registeredDrivers.addIfAbsent(new DriverInfo(driver, da));
        } else {
            // This is for compatibility with the original DriverManager
            throw new NullPointerException();
        }

        println("registerDriver: " + driver);

    }

驱动被添加到了registeredDrivers。
综上,不能使用ClassLoader.loadClass。

Class.forName与new Object

这两者的区别就是new Object可以构造带参构造器。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值