A类不等于A类

发布于 2024-12-04 16:33:37 字数 762 浏览 0 评论 0原文

我们确实有一个包含 TestClass 类对象的缓存 (Map)。另一个类加载器在运行时再次初始化/加载TestClass,因此下面的代码将抛出ClassCastException

TestClass obj1 = (TestClass)map.get("key"); // throws a ClassCastException

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

若有似无的小暗淡 2024-12-11 16:33:38

是的,您的研究指出了正确的方向:由不同类加载器加载的相同类定义被 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 (==).

妄想挽回 2024-12-11 16:33:38

您所经历的就是自定义类加载器存在的原因。它们允许在一个 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.

笑饮青盏花 2024-12-11 16:33:38

谁能给我解释一下背景吗?

正如 Péter Török 已经解释的那样,当从不同的类加载器加载时,它们被认为是不同的。
背景是应用程序服务器应该能够支持应用程序的不同版本,例如,ear 文件中包含的相同库的不同版本。

Anyone able to explain the background to me?

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.

夏末的微笑 2024-12-11 16:33:38

这并不神秘。 Java 语言规范中定义的运行时类型相等如下:

“在运行时,具有相同二进制名称的多个引用类型可能会被不同的类加载器同时加载。这些类型可能代表也可能不代表相同的类型声明。即使两个这样的类型确实代表相同的类型声明,它们被认为是不同的。”

JLS 4.3 .4-当引用类型相同时。 (第二段)

There is no mystery. Runtime equality of types is defined in the Java Language Specification as follows:

"At run time, several reference types with the same binary name may be loaded simultaneously by different class loaders. These types may or may not represent the same type declaration. Even if two such types do represent the same type declaration, they are considered distinct."

JLS 4.3.4 - When reference types are the same. (2nd paragraph)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文