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。
出现的原因,记住以下三点就行了:
- 每个类加载器都有自己的命名空间,命名空间由该加载器及所有父加载器所加载的类组成
- 在同一个命名空间中,不会出现类的完整名字(包括包名)相同的两个类
- 在不同的命名空间中,有可能会出现类的完整名字(包括类的包名)相同的两个类
问题的产生就符合了以上第三条规则
相关文章推荐
- C++ Primer 学习笔记_6_标准库类型 -- 命名空间using与string类型
- PHP学习笔记(七):命名空间
- C++ Primer 学习笔记_91_用于大型程序的工具 --命名空间
- Javascript学习笔记之函数篇(六) : 作用域与命名空间
- XML学习笔记(一):XML中的命名空间
- php命名空间学习笔记。
- C++ 学习笔记(3)命名空间using、字符串、string、vector、迭代器、数组
- PHP学习笔记之命名空间//待完善V1.0
- c++primer学习笔记-----3.1命名空间的using 声明
- SpringMVC4 学习笔记(八) 【命名空间】
- C++学习笔记(九):作用域和命名空间
- C++ Primer 学习笔记_91_用以大型程序的工具 -命名空间
- JVM深入学习(三)类加载深入解析和命名空间
- XML学习笔记(一):XML中的命名空间
- C++ Primer 学习笔记_92_用来大型程序的工具 -命名空间[续1]
- Python学习笔记:作用域和命名空间
- PHP 面向对象程序设计(oop)学习笔记 (五) - PHP 命名空间
- (原创)c#学习笔记03--变量和表达式04--表达式04--命名空间
- 02.django学习笔记(url和应用命名空间)
- C++ Primer 学习笔记_94_用来大型程序的工具 -命名空间[续3]