zoukankan      html  css  js  c++  java
  • 不同类加载器加载同一个class文件

    不同类加载器加载同一个class文件得到的类型也是不同的。

    验证如下:

    D:\00-test目录下,有名为Test.class的文件,其编译前的源码如下:

    public class Test {
        public static int count = 0;
    
        public Test() {
            ++count;
            System.out.println(this.getClass().getClassLoader());
            System.out.println("count: " + count);
        }
    }
    

    每当创建一个对象的时候,静态变量count就会自增,可以利用count的值来判定不同类加载器得到的Class对象是否是同一个。

    创建Main类如下:

    public class Main {
        public static void main(String[] args) throws Exception {
            URLClassLoader loader_1 =
                    new URLClassLoader(new URL[]{new File("D:\00-test").toURI().toURL()});
    
            URLClassLoader loader_2 =
                    new URLClassLoader(new URL[]{new File("D:\00-test").toURI().toURL()});
    
            Class<?> clazz_1 = loader_1.loadClass("Test");
            clazz_1.newInstance();
            Class<?> clazz_2 = loader_2.loadClass("Test");
            clazz_2.newInstance();
        }
    }
    

    main()方法中,首先自定义两个类加载器,分别使用这两个类加载器加载Test.class文件,然后使用得到的Class对象创建实例,最后得到结果如下:

    java.net.URLClassLoader@1b6d3586
    count: 1
    java.net.URLClassLoader@74a14482
    count: 1
    

    可以看到,两个对象的类加载器并不相同,count值却是相同的,这说明这两个实例虽然都是从Test.class中得来,类型却并不相同,从而count只自增一次。

    实际上,在jvms8的5.3.2节有这样一段阐述:

    At run time, a class or interface is determined not by its name alone, but by a pair:
    its binary name (§4.2.1) and its defining class loader. Each such class or interface
    belongs to a single run-time package. The run-time package of a class or interface is
    determined by the package name and defining class loader of the class or interface.
    

    翻译如下:
    在运行时,一个类或者接口并不是单单由它的名称确定的,而是由它的二进制名称以及它的定义类加载器共同确定的。
    每个这样的类或者接口都属于一个运行时包,运行时包则由包名和定义类加载器共同确定。

    上述中所谓的定义类加载器实际上就是getClassLoader()的返回值,而这个概念的产生则跟类加载过程中的“双亲委派机制”有关。

    当要加载一个类时,第一个发起类加载的加载器称之为“初始类加载器”(initiating loader),但是根据“双亲委派机制”,它会先将加载委派给父加载器,如果父加载器加载失败,才会最终由自己尝试加载。而无论哪个加载器加载成功,它就是该类的定义类加载器(defining class loader)。

    -------------------------------------
    吾生也有涯,而知也无涯。
  • 相关阅读:
    Linux centos7 安装 phpMyAdmin
    centos7安装显示中文
    js限制按钮每隔一段时间才能再次点击
    PHPMailer 发送邮件
    jquery click事件中的return false
    安装composer
    生成目录树查看目录结构
    VMware桥接模式下虚拟机ping主机不通
    编译U-Boot时command not found的解决方法
    强制删除文件(夹)的方法
  • 原文地址:https://www.cnblogs.com/SanjiApollo/p/12839682.html
Copyright © 2011-2022 走看看