java虚拟机之类加载器

类加载器实现了类加载阶段中“通过一个类的全限定名来获取描述此类的二进制字节流”的这个动作~
对于任意一个类,都需要由加载它的类加载器和这个类本身一同确立其在java虚拟机中的唯一性,通俗点说:只有两个类是同一个类加载器加载的前提下,才能比较两个类是否“相等”,否则两个类必定不相等!
举个栗子!

public class ClassLoaderTest {
    public static void main(String[] args){
        ClassLoader myLoader = 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) {
                    throw  new ClassNotFoundException();
                }
            }
        };
        try{
            Object obj = myLoader.loadClass("ClassLoaderTest").newInstance();
            System.out.println(obj.getClass());
            System.out.println(obj instanceof  ClassLoaderTest);
        }catch (Exception a){

        }
    }
}

运行结果:
class ClassLoaderTest
false

在这个示例中我们发现,一个是由系统应用程序类加载器加载的,一个是由我们自己定义的类加载器加载的,虽然是同一个Class文件,但依然是两个独立的类,所以结果返回的是false。

从java开发人员的角度来看,类加载器分以下几种

  • 启动类加载器:
    这个类加载器主要负责将存放在<JAVA_HOME>\lib目录中或者被-Xbootclasspath参数所制定的路径中的,并且被虚拟机识别的类库加载到虚拟机内存中。(如rt.jar)
  • 扩展类加载器
    这个类加载器主要负责加载<JAVA_HOME>\lib\ext目录中或者被java.etx.dirs系统变量所制定的路径中的所有类库,开发者可以直接使用扩展类加载器。
  • 应用程序类加载器
    这个类加载器主要负责加载用户类路径(ClassPath)中所指定的类库,开发者可以直接使用扩展类加载器。如果应用程序中没有自定义过自己的类加载器,一般情况下这个就是程序中默认的类加载器!
自定义类加载器
应用程序类加载器
自定义类加载器
扩展类加载器
启动类加载器

上图中展示的类加载器之间的这种层次关系称之为类加载器的双亲委派模型。双亲委派模型要求出来顶层的启动类加载器外,其余的类加载器都应当有自己的父类加载器。这里类加载器之间的父子关系一般不会以继承的关系来是想,而是都用组合关系来复用父加载器的代码。

双亲委派模型的工作过程:如果一个类加载器收到了类加载的请求,它会将这个请求传递给父类,如果父类无法加载,则再由自己去加载。这样的有一个显而易见的好处就是:java类随着它的类加载器一起具备了一种带有优先级的层次关系!
例如:java.lang.Object它存放在rt.jar中。无论哪个加载器想加载它,都会传递到启动类加载器中加载,这样,能确保不会出现多个不同的Object类(因为确定一个类是否是相同的,需要类本身以及加载它的加载器都相同!)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值