Java中的通用方法参数的getClass()

以下Java方法无法编译:

 void foo(T t) { Class klass = t.getClass(); } 

收到的错误是:类型不匹配:无法转换为Class ClassClass Class

有人可以解释为什么Class Class无效,但Class Class

Javadoc说:

实际的结果类型是Class Class where | X | 是擦除调用getClass的表达式的静态类型。 例如,此代码片段中不需要强制转换:

 Number n = 0; Class c = n.getClass(); 

因为T类’类型不会从T延伸。 相反,它从Number扩展,正如您在 。 就那么简单。

一个更好的问题是:

以下为什么不编译?

  void foo(T t) { Class class1 = t.getClass(); } 

答案是Object#getClass()返回带有无界通配符的Class ? 因为对象本身并不直接了解其在任意方法中所期望的generics类型。

这有点傻。 对于大多数用例来说,如果x.getClass()返回Class Class ,而不是擦除的Class Class

擦除是导致信息丢失的原因,使您的代码显然是安全的,无法编译。 t.getClass()返回Class Class|T| = Number |T| = Number ,所以返回Class Class

擦除(由语言规范强制要求)是为了保持理论上的正确性。 例如

 List x = ...; Class c1 = x.getClass(); // ok Class> c2 = x.getClass(); // error 

虽然c2看起来很合理,但在Java中, List实际上没有这样的类。 List只有一个类。 所以允许c2理论上是不正确的。

这种forms在现实世界的用法中产生了很多问题,程序员可以推断出Class Class对于他们的目的是安全的,但必须处理已删除的版本。

您可以简单地定义自己的getClass ,返回未擦除的类型

 static public  Class getFullClass(X x) return (Class)(Class) x.getClass() ;  void foo(T t) { Class klass = getFullClass(t); }