【问题标题】:How to meaningfully define hashCode and equals for a java.lang.Class<T>?如何为 java.lang.Class<T> 有意义地定义 hashCode 和 equals?
【发布时间】:2012-09-16 12:34:57
【问题描述】:

如果需要使用Class&lt;T&gt; 作为Map 键的一部分,那么定义hashCodeequals 的正确方法是什么?
Class&lt;T&gt; 继承自 Object 的那些 Object 检查引用相等性并将内存地址作为哈希码返回,但在我看来,尚不清楚 equalshashCode 的有意义定义是什么 @987654330 @.
例如,我应该使用theClass.getClass().hashCode();(我们有Class&lt;T&gt; theClass;)来使用实际实例的方法吗?
但这似乎不是正确的做法。
例如在javadoc 中为Class&lt;T&gt;

每个数组也属于一个类,反映为一个类 由具有相同元素类型的所有数组共享的对象和 维数

所以在某些情况下,相同的Class&lt;T&gt; 似乎在对象之间共享?那么遵循的方法是什么?也许使用theClass.hashCode()theClass.equals() 来使用引用相等?这里完全不确定。

【问题讨论】:

  • 没有什么要定义的,因为 hashcode 和 equals 已经实现了,我很难想象如何,甚至更难想象你为什么要改变那个实现。
  • @JensSchauder:使用 Eclipse 自动生成 hashCodeequals 它发出警告,抱怨 hashCodeequals 没有为 Class 定义。这让我担心是否这是一个有效的警告,我应该做点什么。
  • 我不知道你想做什么,但'Class'是一个属于java本身的类。你不能为它实现任何东西。您尝试在其中添加 hashCode 和 equals 的源文件的全名是什么?
  • @JensSchauder:不确定源文件的要求。Class&lt;T&gt; 是可以用作Map 中的键的类的成员
  • 不,Class 是类 java.lang.Class 实现的类型。每个类 T 都有一个实例。它的类型是 Class

标签: java hash hashmap equals hashcode


【解决方案1】:

java.lang.Object 继承的hashCodeequals java.lang.Class 的实现是有意义的并且通常是适当的,因为一个类的所有实例都保证返回相同 Class 对象来自getClass(),即

new Integer(2).getClass() == new Integer(3).getClass();

这有点隐藏在文档中; javadoc of getClass() 写道:

返回:

表示此对象的运行时类的 Class 对象。

另见:

Literals,Java™ 语言规范的第 15.8.2 节。

That section 写道:

类字面量计算为由当前实例的类的定义类加载器(第 12.2 节)定义的命名类型(或 void)的 Class 对象。

section 12.2 写道:

行为良好的类加载器维护这些属性:

  • 给定相同的名称,一个好的类加载器应该总是返回相同的类对象。
  • ...

恶意类加载器可能会违反这些属性。但是,它不会破坏类型系统的安全性,因为 Java 虚拟机对此进行了防范。

是的,如果相同的类定义被不同的类加载器加载,类对象将不相等。由于运行时将它们视为独立的类(它们恰好共享相同的名称,但不需要相似,更不用说二进制兼容了),这通常是需要的。

【讨论】:

  • 关于此的旁注:像 Tomcat 这样的应用程序使用分层类加载器,这可能会咬你。 Tomcat 为它的所有应用程序提供了自己的类加载器堆栈。
【解决方案2】:

String getName() 方法返回类的唯一字符串表示。如果您的程序不使用多个类加载器,则可以将此 String for equals/hashCode 用作普通 String。

【讨论】:

  • 但我不这样做 Map&lt;Class&lt;T&gt;,T&gt;。我的问题是 Class&lt;T&gt; 何时是密钥的部分。不是密钥本身
  • @Cratylus 答案是一样的;您使用 getName() 返回 Class 对象的唯一字符串表示;你在 hash/equals 中使用这个字符串,就好像它是一个 String 实例字段一样。
猜你喜欢
  • 2013-07-22
  • 1970-01-01
  • 2021-12-29
  • 2013-02-17
  • 1970-01-01
  • 2015-04-25
  • 1970-01-01
  • 1970-01-01
  • 2017-11-19
相关资源
最近更新 更多