java 反射 this_Java核心(二)——this/反射/注解

ClassLoader类负责加载类,它的核心方法是loadClass(),传入需要加载的类名,它会帮你加载:

protected Class> loadClass(String name, boolean resolve) throws ClassNotFoundException {

synchronized (getClassLoadingLock(name)) {

// 首先,检查是否已经加载该类

Class> c = findLoadedClass(name);

if (c == null) {

long t0 = System.nanoTime();

try {

// 如果尚未加载,则遵循父优先的等级加载机制(所谓双亲委派机制)

if (parent != null) {

c = parent.loadClass(name, false);

} else {

c = findBootstrapClassOrNull(name);

}

} catch (ClassNotFoundException e) {

// ClassNotFoundException thrown if class not found

// from the non-null parent class loader

}

if (c == null) {

// 模板方法模式:如果还是没有加载成功,调用findClass()

long t1 = System.nanoTime();

c = findClass(name);

// this is the defining class loader; record the stats

sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);

sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);

sun.misc.PerfCounter.getFindClasses().increment();

}

}

if (resolve) {

resolveClass(c);

}

return c;

}

}

// 子类应该重写该方法

protected Class> findClass(String name) throws ClassNotFoundException {

throw new ClassNotFoundException(name);

}

加载.class文件大致可以分为3个步骤:

检查是否已经加载,有就直接返回,避免重复加载

当前缓存中确实没有该类,那么遵循父优先加载机制(双亲委派机制),加载.class文件

上面两步都失败了,调用findClass()方法加载

ClassLoader类本身是抽象类,而抽象类是无法通过new创建对象的,所以它并没有实现最核心的findClass()方法,直接抛了异常。此处又是应用了模板方法模式,具体的findClass()方法丢给子类实现。

正确的做法是,子类重写覆盖findClass(),在里面写自定义的加载逻辑:

@Override

public Class> findClass(String name) throws ClassNotFoundException {

try {

/*自己另外写一个getClassData()

通过IO流从指定位置读取xxx.class文件得到字节数组*/

byte[] datas = getClassData(name);

if(datas == null) {

throw new ClassNotFoundException("类没有找到:" + name);

}

//调用类加载器本身的defineClass()方法,由字节码得到Class对象

return defineClass(name, datas, 0, datas.length);

} catch (IOException e) {

e.printStackTrace();

throw new ClassNotFoundException("类找不到:" + name);

}

}

defineClass()是父类ClassLoader里定义的方法,目的是根据.class文件的字节数组byte[] b造出一个对应的Class对象。我们无法得知具体是如何实现的,因为最终它会调用一个native方法:

c357b9edaa8901932f1bc04a3e40d0ff.png

总的流程:

ffe6b0713a429fed84c385e233650d17.png

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值