剑指Offer(JVM)——loadClass和forName区别

先来说一下类的加载方式,一个类被加载出来有两种方式,分别是显示加载和隐式加载:

  • 显示加载:loadClass和forName等
  • 隐式加载:new

隐式加载是通过new一个class来获得类的实例相对于显示加载更加好的地方在于它可以直接调用有参构造。

显示调用原则不是很简单当获取到class对象之后需要调用class的new Instance()方法才能获取到类的实例,调用new Instance()不能进行参数的填充。

接下来来说一下loadClass和forName的区别。。

当调用这两个方法时候都可以知道类对应的全部属性和方法,对于一个任意的对象都可以调用其属性和方法。

从类的装载过程来解决这个问题:
装载: 一个class对象的生成过程,class对象的装载一共分为三步:

  1. 加载

ClassLoader的loadClass方法将类的字节码加载到内存中,这些类型数据转换成运行时方法区的类型数据,运行时候会生成一个.class,成为访问当前这个java文件的入口。

  1. 链接

检验.class文件是否通过编译,并且同时检查安全性;准备为类变量分配存储空间并设置类变量的初始值;解析JVM将常量池内的符号引用转换为直接引用。

  1. 初始化

执行类变量相关的赋值和静态的代码块。

Class.forName得到的class是初始化完成的,ClassLoader.loadClass得到的class只是完成了加载过程其余的步骤还没有完成。

编写一个实体类包含静态方法块:

public class Person {

    private String name;

    public void sayHello(String sentence){
        System.out.println(sentence + " " + name);
    }

    private String hello(String flag){
        return "Hello" + " " + flag;
    }
    
    static {
        System.out.println("I love you forever");
    }
}

执行这段代码,发现使用loadClass的结果只是完成第一步:检查编译是否能够通过,结果就是没有输出静态代码块中的内容。
在这里插入图片描述
使用Class.forName()加载实体类,完成初始化步骤静态代码块中的内容会输出:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值