Java:有界类型的getClass()

Sma*_*ker 13 java type-erasure type-parameter

当我在使用泛型时,我发现了一些东西.在下面的示例中,doStuff1编译但doStuff2不:

public <T extends Foo> void doStuff1(T value) {
    Class<? extends Foo> theClass = value.getClass();
}

public <T extends Foo> void doStuff2(T value) {
    Class<? extends T> theClass = value.getClass();
}
Run Code Online (Sandbox Code Playgroud)

所以,我查阅了文档Object.getClass(),发现了这个:

实际的结果类型是Class <?extends | X |> where | X | 是调用getClass的表达式的静态类型的擦除.

这让我有点好奇.为什么getClass()这样设计?如果适用的话,我可以理解将类型转换为它们的原始类,但我认为没有明显的理由为什么它们必须使它也被杀掉T.有没有一个特定的原因,它也可以摆脱它,或者它只是一个普遍的"让我们摆脱一切因为它更容易;谁会永远需要它"的方法?

Zho*_*gYu 9

如果getClass()回来Class<? extends X>,没有什么不好的事情会发生; 实际上它会帮助很多用例.

唯一的问题是,它在理论上是不正确的.如果一个对象是一个ArrayList<String>,它class不可能Class<ArrayList<String>>- 没有这样的类,只有一个Class<ArrayList>.

这实际上与擦除无关.如果有一天Java获得完整的reified类型,getClass()仍然应该返回Class<? extends |X|>; 但是应该有一个新方法,比如getType()可以返回更详细的方法Type<? extends X>.(但是,getType可能会与许多现有的类使用自己的getType方法冲突)

对于时间安排,因为Class<? extends X>在很多情况下可能有用,我们可以设计我们自己的方法来做到这一点

static <X> Class<? extends X> myGetClass(X x){ ... }
Run Code Online (Sandbox Code Playgroud)

但是可以理解他们不会把这种黑客放在标准的lib中.