1

我已经在网上潜伏了一段时间,但还没有找到答案。有人Class<T>在这里提到 SO(我认为)是关键,但我再也找不到该帖子了。无论如何,这个问题应该得到一个正确的答案(如果上面有一千个帖子线程道歉)。

Class<T>不可变的吗?它可以安全有效地用作关键(不断hashCode()执行)吗?

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

编辑:谈论Java。

4

4 回答 4

2

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

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

JavaClass类满足以下要求:

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

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

于 2013-02-21T03:23:55.307 回答
2

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是一个单例,它的hashCode和equals是基于它的身份的,需要注意的是一个类在不同的类加载器中会有不同的实例,所以MyClass.class from classloader1 != MyClass.class from类加载器2

于 2013-02-21T05:15:41.923 回答
0

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

public final Class<?> getClass()

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

实际的结果类型是删除被调用的表达式的静态类型的Class<? extends |X|>地方。例如,此代码片段中不需要强制转换:|X|getClass

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

因此,对于任何实例T obj,和返回相同的(不可变的)对象。T obj2obj.getClass()obj2.getClass()Class<T>

LinkedList<T> l1但是,请注意类型擦除:对于 a或 a而言,情况并非如此LinkedList<U> l2,因为两者都将返回类型擦除类Class<LinkedList>,而不是Class<LinkedList<T>>特定于 的a T

于 2013-02-21T03:49:08.987 回答
0

是的(假设类加载器表现良好,即 irClass在给定相同名称时总是返回相同的对象。)

The hashCode of a Class instance is its object identity (Class do not redefine hashcode), which remains constant for the lifetime of the object. The JLS states that one must not unload a class or interface while its loader is potentially reachable (in order to avoid classes to be reloaded, which would not be transparent to the application, because the object identity of the Class object would be different).

Note that classes of the same name, but loaded by different class loaders, have different hash codes. Usually this should not be an issue since they will be different run-time types, and their instances will not be assignment-compatible.

于 2013-02-26T04:04:26.760 回答