zoukankan      html  css  js  c++  java
  • 类加载器命名空间深度解析与实例分析

    在上一次【https://i.cnblogs.com/posts?categoryid=1154466】最后写了一个貌似没啥意义的程序,回顾一下:

    其结果为true的原因并非是因为loader1和loader2都是MyTest16的实例哈,如果是这样理解的话说明对类的双亲委托机制就不太了解,这里再解释一下原因:

    貌似程序也没有异常都能正常执行,那写它有啥意义呢?其实写它是有目的的,这次会基于它进一步进行修改,最终会发现一个非常惊奇的异常,下面进行改造:

    很显然直接运行其结果跟之前一样,因为还是由系统类加载器去加载,工程中有MyPerson.class文件,如下:

    此时咱们将工程当中生成的MyPerson.class文件拷至到桌面的指定目录下:

    然后将MyPerson.class从咱们的工程当中删除掉:

    那此时再运行结果又会如何呢?

    呃~~抛异常了,下面来分析一下:

    其中为啥返回false的更深层次的原因还是跟命名空间相关,具体是:clazz1是由loader1所加载的,而calzz2是由loader2加载的,而loader1和loader2从双亲的层次关系来看这两者是没有任何关系的,也就会在JVM中形成两个命名空间,也就是两个独立的内存,具体原因还是之前所学习理论如下:

    也就是咱们目前的情况就属于图上的第三点:虽说clazz1和clazz2的完整名字及类的包名都是一模一样的,但是它俩是属于不同的命名空间,另外为了更进一步理解还需引入另一个理论:不同类加载器的命名空间关系,具体如下:

    • 同一个命名空间内的类是相互可见的。
    • 子加载器的命名空间包含所有父类加载器的命名空间。因此由子加载器加载的类能看见父加载器加载的类,例如系统类加载器回载的类能看见根类加载器加载的类。
    • 由父类加载器加载的类不能看见子加载器加载的类。
    • 如果两个加载器之间没有直接或间接的父子关系,那么它们各自加载的类相互不可见。【符合咱目前的场景】

    既然不可见那很显然clazz1和clazz2是两个不同的对像,那当然返回false喽,所以可见命名空间是多么的重要,所以也反复被提及到。

    继续往下分析结果:

    这也是写这个程序目的之所在,让咱们会觉得非常之惊奇,而如果根据咱们目前分析的上下文来理解那就变得理解应当了,因为clazz1和clazz2在不同的命名空间里面而又不是父子关系所以是相互不可见的,所以:

    那为啥这个程序要这样设计专门在MyPerson中传一个Object然后进行向下类型转换,而不是直接传一个Person类型的参数呢?这是有原因的,咱们来试一下:

    然后重新编译,然后再将MyPerson.class重新拷贝到桌面,并且将工程当中的MyPerson.class给删除掉,然后再运行:

    所以还是将代码还原成Object参数类型。

  • 相关阅读:
    caffe常用层: batchNorm层和scale层
    简述configure、pkg-config、pkg_config_path三者的关系
    python删除list中元素的三种方法
    Leetcode 872. Leaf-Similar Trees
    Leetcode 508. Most Frequent Subtree Sum
    Leetcode 572. Subtree of Another Tree
    Leetcode 894. All Possible Full Binary Trees
    Leetcode 814. Binary Tree Pruning
    Leetcode 557. Reverse Words in a String III
    python 多维list声明时的小问题
  • 原文地址:https://www.cnblogs.com/webor2006/p/9157847.html
Copyright © 2011-2022 走看看