Java ClassLoader的简单介绍


Java ClassLoader的简单介绍

本文是阅读《深入理解Java虚拟机》第七章类加载器相关部分过程中生成的阅读笔记。简单介绍了ClassLoader的是什么,主要的类型和双亲委派模型。

ClassLoader是什么

虚拟机设计团队把类加载阶段中的“通过一个类的全限定名来获取描述此类的二进制字节流”这个动作放到Java虚拟机外部去实现,以便让应用程序自己决定如何去获取所需要的类。实现这个动作的代码模块称为“类加载器”。

​ –《深入理解Java虚拟机》(周志明)

ClassLoader就是这里提到的类加载器。类加载器的作用就是根据类的全限定名获取类的二进制字节流。这个动作在Java虚拟机的外部实现。

类与类加载器的关系

类加载器除了加载类的作用外,还和被加载的类本身共同确保类的唯一性。对于两个相同的Class文件,当使用不同的类加载器加载时他们就i是不同的。

例如当使用了不同ClassLoader加载同一个类时,会导致instanceof的结果为false。

package com.suifeng.loader;

import java.io.IOException;
import java.io.InputStream;

public class ClassLoaderTest {

    public static void main(String[] args) throws Exception{
        ClassLoader myClassLoader = new ClassLoader() {
            @Override
            public Class<?> loadClass(String name) throws ClassNotFoundException {
                try {
                    String fileName = name.substring(name.lastIndexOf(".") + 1) + ".class";
                    InputStream is = getClass().getResourceAsStream(fileName);
                    if (is == null) {
                        return super.loadClass(name);
                    }

                    byte[] b = new byte[is.available()];
                    is.read(b);
                    return defineClass(name, b, 0, b.length);
                } catch (IOException e) {
                    e.printStackTrace();
                    throw new ClassNotFoundException(name);
                }
            }
        };
        Class<?> aClass = myClassLoader.loadClass("com.suifeng.loader.TestClass");
        Object obj = aClass.newInstance();

        System.out.println(obj.getClass());
        System.out.println(obj instanceof com.suifeng.loader.TestClass);
    }
}

输出结果为

class com.suifeng.loader.TestClass
false

可以看到这里的obj是TestClass的对象,但使用instanceof关键字判断时仍然返回false。这是因为使用了不同类加载器jvm将他们识别为两个不同的类。obj是自定义类加载的,而另一个是由系统应用程序类加载器加载的。

类加载器类型

Java提供了三种类加载器。分别是启动类加载器扩展类加载器应用程序类加载器


文章作者: suifeng
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 suifeng !
  目录