您的位置:首页 > 其它

JVM学习笔记(3.X)之类加载器命名空间补充

2019-10-25 23:44 453 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/qq_24286273/article/details/102751722

JVM学习笔记(3.X)之类加载器命名空间补充

本篇是类加载器命名空间补充,只是记录一段奇怪的

代码,以此来加深对命名空间的理解,下面贴下代码及结果

MyPerson类

package com.zh.classloader;

/**
* @author Jack
* @version 1.0
* @date 2019/10/24 23:27
*/
public class MyPerson {

private MyPerson myPerson;

public void setMyPerson(Object object) {
this.myPerson = (MyPerson) object;
}
}

MyTest21类

package com.zh.classloader;

import java.lang.reflect.Method;

/**
* @author Jack
* @version 1.0
* @date 2019/10/24 23:28
*/
public class MyTest21 {

public static void main(String[] args) throws Exception {
MyClassLoader loader1 = new MyClassLoader("loader1");
MyClassLoader loader2 = new MyClassLoader("loader2");

loader1.setPath("C:\\Users\\Jack\\Desktop\\");
loader2.setPath("C:\\Users\\Jack\\Desktop\\");

Class<?> clazz1 = loader1.loadClass("com.zh.classloader.MyPerson");
Class<?> clazz2 = loader2.loadClass("com.zh.classloader.MyPerson");

//false 两个类加载器命名空间不同
System.out.println(clazz1 == clazz2);

Object object1 = clazz1.newInstance();
Object object2 = clazz2.newInstance();

//不同类加载器加载出来的Class对象所实例化出来的MyPerson不可见,所以无法转换
Method method = clazz1.getMethod("setMyPerson", Object.class);
method.invoke(object1, object2);

}
}
D:\Java\jdk1.8.0_152\bin\java.exe "-javaagent:E:\Program Files\JetBrains\IntelliJ IDEA 2018.2.5\lib\idea_rt.jar=63090:E:\Program Files\JetBrains\IntelliJ IDEA 2018.2.5\bin" -Dfile.encoding=UTF-8 -classpath D:\Java\jdk1.8.0_152\jre\lib\charsets.jar;D:\Java\jdk1.8.0_152\jre\lib\deploy.jar;D:\Java\jdk1.8.0_152\jre\lib\ext\access-bridge-64.jar;D:\Java\jdk1.8.0_152\jre\lib\ext\cldrdata.jar;D:\Java\jdk1.8.0_152\jre\lib\ext\dnsns.jar;D:\Java\jdk1.8.0_152\jre\lib\ext\jaccess.jar;D:\Java\jdk1.8.0_152\jre\lib\ext\jfxrt.jar;D:\Java\jdk1.8.0_152\jre\lib\ext\localedata.jar;D:\Java\jdk1.8.0_152\jre\lib\ext\nashorn.jar;D:\Java\jdk1.8.0_152\jre\lib\ext\sunec.jar;D:\Java\jdk1.8.0_152\jre\lib\ext\sunjce_provider.jar;D:\Java\jdk1.8.0_152\jre\lib\ext\sunmscapi.jar;D:\Java\jdk1.8.0_152\jre\lib\ext\sunpkcs11.jar;D:\Java\jdk1.8.0_152\jre\lib\ext\zipfs.jar;D:\Java\jdk1.8.0_152\jre\lib\javaws.jar;D:\Java\jdk1.8.0_152\jre\lib\jce.jar;D:\Java\jdk1.8.0_152\jre\lib\jfr.jar;D:\Java\jdk1.8.0_152\jre\lib\jfxswt.jar;D:\Java\jdk1.8.0_152\jre\lib\jsse.jar;D:\Java\jdk1.8.0_152\jre\lib\management-agent.jar;D:\Java\jdk1.8.0_152\jre\lib\plugin.jar;D:\Java\jdk1.8.0_152\jre\lib\resources.jar;D:\Java\jdk1.8.0_152\jre\lib\rt.jar;D:\jvm_study\target\classes com.zh.classloader.MyTest21
findClass
loadClassData
Exception in thread "main" java.lang.reflect.InvocationTargetException
findClass
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
loadClassData
false
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.zh.classloader.MyTest21.main(MyTest21.java:30)
Caused by: java.lang.ClassCastException: com.zh.classloader.MyPerson cannot be cast to com.zh.classloader.MyPerson
at com.zh.classloader.MyPerson.setMyPerson(MyPerson.java:13)
... 5 more

Process finished with exit code 1

出现了包名+类名完全相同的两个类报ClassCastException。

出现的原因,记住以下三点就行了:

  • 每个类加载器都有自己的命名空间,命名空间由该加载器及所有父加载器所加载的类组成
  • 在同一个命名空间中,不会出现类的完整名字(包括包名)相同的两个类
  • 在不同的命名空间中,有可能会出现类的完整名字(包括类的包名)相同的两个类

问题的产生就符合了以上第三条规则

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: