类加载器简介
在介绍双亲委托模型之前, 先介绍一下类加载器. 类加载器通过一个类的全限定名来转换为描述这个类的二进制字节流.
对于任意一个类, 被同一个类加载器加载后都是唯一的, 但如果被不同加载器加载后, 就不是唯一的了. 即使是源于同一个 Class 文件, 被同一个 JVM 加载, 只要加载类的加载器不同, 那么类就不同.
如何判断类是否相同, 可以使用 Class 对象的 equals()方法, isAssignableFrom()方法, isInstance()方法的返回结果进行判断, 也可以使用 instanceof 关键字进行对象所属关系的判断.
下面我们写一个不同类加载器加载后的类, 看一下对 instanceof 关键字运算有什么影响:
- public class OneMoreStudy {
- public static void main(String[] args) throws Exception {
- ClassLoader myLoader = new ClassLoader() {
- @Override
- public Class<?> loadClass(String name) throws ClassNotFoundException {
- try {
- String fileName = name.substring(name.lastIndexOf(".") + 1) + ".class";
- InputStream inputStream = getClass().getResourceAsStream(fileName);
- if (inputStream == null) {
- return super.loadClass(name);
- }
- byte[] array = new byte[inputStream.available()];
- inputStream.read(array);
- return defineClass(name, array, 0, array.length);
- } catch (IOException e) {
- throw new ClassNotFoundException(name);
- }
- }
- };
- Object object = myLoader.loadClass("OneMoreStudy").newInstance();
- System.out.println("class name:" + object.getClass().getName());
- System.out.println("instanceof:" + (object instanceof OneMoreStudy));
- }
- }
运行结果:
- class name: OneMoreStudy
- instanceof: false
在运行结果中, 第一行可以看出这个对象确实是 OneMoreStudy 类实例化出来的, 但在第二行中 instanceof 运算结果是 false, 说明在 JVM 中存在两个 OneMoreStudy 类, 一个是由系统应用程序类加载器加载的, 另一个是由我们自定义的类加载器加载的. 虽然都是来自同一个 Class 文件, 在同一个 JVM 里, 但是被不同的类加载器加载后, 仍然是两个独立的类.
- protected Class<?> loadClass(String name, boolean resolve)
- throws ClassNotFoundException
- {
- synchronized (getClassLoadingLock(name)) {
- // 首先, 检查该类是否已经被加载过了
- Class<?> c = findLoadedClass(name);
- // 如果没有加载过, 就调用父类加载器的 loadClass()方法
- if (c == null) {
- long t0 = System.nanoTime();
- try {
- if (parent != null) {
- c = parent.loadClass(name, false);
- } else {
- // 如果父类加载器为空, 就使用启动类加载器
- c = findBootstrapClassOrNull(name);
- }
- } catch (ClassNotFoundException e) {
- // 如果在父类加载器中找不到该类, 就会抛出 ClassNotFoundException
- }
- if (c == null) {
- // 如果父类找不到, 就调用 findClass()来找到该类.
- long t1 = System.nanoTime();
- c = findClass(name);
- // 记录统计数据
- sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
- sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
- sun.misc.PerfCounter.getFindClasses().increment();
- }
- }
- if (resolve) {
- resolveClass(c);
- }
- return c;
- }
- }
来源: https://www.cnblogs.com/heihaozi/p/12143308.html