代码之家  ›  专栏  ›  技术社区  ›  Andrea Richiardi

Class<T>在Java中是不可变的吗?也称为,Class<T<是HashMap的安全密钥吗?

  •  1
  • Andrea Richiardi  · 技术社区  · 12 年前

    我已经潜伏了一段时间,但还没有找到答案。 有人提到 Class<T> 作为SO上的关键(我想),但我再也找不到这个帖子了。 无论如何,这个问题应该得到一个恰当的答案(如果上面有一千条帖子,请道歉)。

    类别<T> 不变的它能否安全有效地用作密钥(常量 hashCode() 过度执行)?

    我的猜测是肯定的,因为类的定义在运行时不会改变。但我不太确定。。。非常感谢。

    编辑:谈论Java。

    4 回复  |  直到 12 年前
        1
  •  2
  •   Perception    12 年前

    Java中的不可变对象是指不能通过任何正常(非反射)执行路径更改其内部状态的对象。这意味着:

    • 该类没有定义可访问的方法来改变其内部状态
    • 类的设计方式是防止子类改变其内部状态

    Java语言 Class 类满足这些要求:

    • 它没有提供改变其内部状态的方法。
    • 类本身是 final ,并且不能细分。

    当然,实际的类定义是由JVM通过类加载器加载的,一旦定义好,就会在JVM的生存期内设置,并且不会更改。

        2
  •  2
  •   Evgeniy Dorofeev    12 年前

    1) 我不确定它是否可以被称为不可变的,至少在古典意义上是这样,看看吧

    public final class Class<T>
        ...
        native void setSigners(Object[] signers);
        ...
        native void setProtectionDomain0(java.security.ProtectionDomain pd);
        ...
        void setAnnotationType(AnnotationType type) 
        ...
    

    2) 我们可以在HashMap中使用它,Class是一个singleton,它的hashCode和equals基于它的标识,但需要注意的是,一个类在不同的类加载器中会有不同的实例,所以classloader1中的MyClass.Class!=来自classloader2的MyClass.class

        3
  •  0
  •   Andrew Mao    12 年前

    这个 hashCode() 方法 Class 没有被覆盖,但是JDK指定了以下关于 getClass() 方法:

    public final Class<?> getClass()
    

    返回此对象的运行时类。 返回的Class对象是由锁定的对象 static synchronized 所表示类的方法。

    实际结果类型为 Class<? extends |X|> 哪里 |X| 是对表达式的静态类型的擦除 getClass 被调用。例如,在这个代码片段中不需要强制转换:

    Number n = 0;
    Class<? extends Number> c = n.getClass(); 
    

    因此,在任何情况下 T obj , T obj2 , obj.getClass() obj2.getClass() 返回相同(不可变) Class<T> 对象

    但是,要小心类型擦除:对于 LinkedList<T> l1 LinkedList<U> l2 ,因为两者都将返回类型擦除类 Class<LinkedList> ,不是 Class<LinkedList<T>> 这是针对 T .

        4
  •  0
  •   Javier user3138333    12 年前

    是的(假设类加载器已经准备好了,因为ir总是返回相同的结果 Class 对象的名称相同。)

    这个 hashCode 实例是其对象标识( 不重新定义 hashcode ),在对象的生命周期内保持不变。这个 JLS 声明 当类或接口的加载程序可能可访问时,不能卸载该类或接口 (为了避免重新加载类,这对应用程序来说是不透明的,因为 对象将不同)。

    请注意,相同名称但由不同的类加载器加载的类具有不同的哈希代码。通常情况下,这不应该是一个问题,因为他们会 different run-time types ,并且它们的实例将不兼容赋值。