A类不等于A类
我们确实有一个包含 TestClass
类对象的缓存 (Map
)。另一个类加载器在运行时再次初始化/加载TestClass
,因此下面的代码将抛出ClassCastException
:
TestClass obj1 = (TestClass)map.get("key"); // throws a ClassCastException
好吧,到目前为止我确实理解这个问题。
因此,我试图查找背景信息为什么 TestClass.class
不等于 TestClass.class
。我假设不同的类加载器为 ReferenceType 设置了不同的 id?有谁能给我解释一下背景吗?
我找到的最佳页面: http://www.objectsource.com/j2eechapters/Ch21-ClassLoaders_and_J2EE.htm
We do have a cache (Map
) with objects of Class TestClass
. Another classloader initializes/loads TestClass
at runtime again, so below code will threw a ClassCastException
:
TestClass obj1 = (TestClass)map.get("key"); // throws a ClassCastException
ClassCastException when casting to the same class
Alright, I do understand this issue up to this point.
So, I was trying to find background information why is TestClass.class
not equals TestClass.class
. I assume that the different classloader set a different id to the ReferenceType? Anyone able to explain the background to me?
Best page I've found:
http://www.objectsource.com/j2eechapters/Ch21-ClassLoaders_and_J2EE.htm
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
是的,您的研究指出了正确的方向:由不同类加载器加载的相同类定义被 JVM 视为两个不同的类。因此,它们之间的转换失败,并出现
ClassCastException
。我认为差异只是因为有两个不同的类令牌对象在起作用。它必须是这样的,因为不同加载器加载的类实际上可能是同一类的不同版本。众所周知,每个类的类标记都是唯一的(即在同一个类加载器领域内)。如果 JVM 开始通过类标记的各种属性而不是通过物理相等性 (
==
) 来比较类标记,就会引发大量蠕虫。Yes, your research points to the right direction: the same class definition loaded by different class loaders is seen as two distinct classes by the JVM. Thus casting between them fails with
ClassCastException
.I think the difference is simply because there are two distinct class token objects in play. It has to be like this, since the classes loaded by the different loaders may in fact be different versions of the same class. It is known that the class token for every class is unique (within the same classloader realm, that is). It would open up a can of worms if the JVM started to compare class tokens by their various attributes, rather than by physical equality (
==
).您所经历的就是自定义类加载器存在的原因。它们允许在一个 JVM 中加载具有相同名称的不同类。 JVM 中类的标识由类名和类加载器组成的元组给出。在 Java 语言中,类仅通过完全限定名称来标识。
What you experienced is the reason why custom class loaders exist. They allow to load different class with the same name in one JVM. The identity of a class in a JVM is given by the tuple consisting of the class name and the class loader. In the language Java a class is identified just by fully qualified name.
正如 Péter Török 已经解释的那样,当从不同的类加载器加载时,它们被认为是不同的。
背景是应用程序服务器应该能够支持应用程序的不同版本,例如,ear 文件中包含的相同库的不同版本。
As Péter Török already explained they are considered different when loaded from different classloaders.
The background is that an application server should be able to support different versions of an application e.g. different versions of the same libraries included in your ear-files.
这并不神秘。 Java 语言规范中定义的运行时类型相等如下:
JLS 4.3 .4-当引用类型相同时。 (第二段)
There is no mystery. Runtime equality of types is defined in the Java Language Specification as follows:
JLS 4.3.4 - When reference types are the same. (2nd paragraph)