
动态类加载
image.png
image.png
各类方法调用情况
无参方法
image.png
有参方法
image.png
静态方法
image.png
赋值
image.png
==所以说Java的类在初始化的时候就会调用静态代码块==
获取类
image.png
所以class关键字只对Java类进行加载,并不会进行初始化
==类在实例化的时候会调用构造代码块==
动态加载类
Class.forName()
image.png
我们跟进去看看

image.png
这里没有,我们可以看看它重载的另一种方法

image.png
它是否初始化的值是在这里确定的

image.png
也就是说它默认是初始化了的
我们尝试使用这个重载方法进行观察
代码如下
java
1 | ClassLoader cl = ClassLoader.getSystemClassLoader(); |
image.png
在这里我们用了一个类加载器,那么如果我们使用这个类加载器去加载类,也就是用它的loadClass方法,它是否会对类进行初始化呢
image.png
我们发现输出为空,那么很明显loadClass方法不会对类进行初始化
我们来瞅瞅类加载的具体实现
image.png
但如果我们打印cl变量就知道,这个加载器是一个app类加载器,我们去这个位置找找它的loadClass方法
image.png
image.png
但是这个方法是两个参数的,并不符合我们的调用
于是它就去了它的父类,也就走到了我们刚才强制步入的那个loadClass里
但是它又调用了两个参数的loadClass,所以下一步肯定又是回来

image.png
然后走到这里,它又调用了它父类的loadClass

image.png
然后check它是否被加载过

image.png
然后看它的父类是否存在,如果有的话就调用它父类的,如果没有就会去BootstrapClass
我们可以看到在这里的时候它的parent不是null

image.png
但是当我们继续往下走然后步入
它又回到了这里

image.png
这时如果我们再走到parent这里

image.png
就会发现parent成null了
image.png
那是因为ExtClassLoader里就没有loadClass方法,所以它开始找BootstrapClass,然后还是没有找到

image.png
我们在这里继续跟进去

image.png
莫名其妙到了URLClassLoader,但我们去查的时候会发现无论是appClassLoader还是ExtClassLoader,它们都没有findClass这个方法
所以就去找了他俩的父类
然后我们走到了这里

image.png
我们发现它是在

image.png
这个时候完成的类加载
我们跟进去发现它又调用了另一个defineClass

image.png

image.png
它又跑到SecureClassLoader里了

image.png
显而易见的又是父类
然后它又调用了另一个重载的defineClass
最后发现它又回到了ClassLoader里

image.png
我们重点关注这个

image.png

image.png
发现它是一个native方法,也就是在这里完成了类加载

image.png
从这里的返回值c也就能很好的看出来了
然后层层返回,就结束了

image.png
继承关系如下:
ClassLoader->SecureClassLoader->URLClassLoader->AppClassLoader
调用关系
loadClass->findClass->defineClass(从字节码加载)
URLClassLoader任意类加载
我直接用我最开始学Java语法时候生成的.class文件了
java
1 | URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{new URL("file:///D:\\codefile\\java\\")}); |
我们这里的协议还可以换成http用来加载远程类,如果我们平时做题能控制到这里,那么就很有趣了
defineClass加载
代码如下
java
1 | Method defineClassMethod = ClassLoader.class.getDeclaredMethod("defineClass",String.class,byte[].class,int.class,int.class); |
急了,写ClassLoader的时候选错包了,运行好几次才发现跑util下去了,应该选java.lang的那个
unsafe.defineClass字节码加载(spring中可以直接生成
image.png
它里面也有一个defineClass方法

image.png
最终代码如下
java
1 | Class c = Unsafe.class; |
本文是原创文章,采用CC BY-NC-SA 4.0协议,完整转载请注明来自fault`s blog
评论 ()
Powered By Valine
v1.5.2
v1.5.2