给定:
public class C<T> {
private class D {
public boolean equals( Object o ) {
if ( !(o instanceof D) ) // line 4
return false;
D other = (D)o; // line 6
return i == other.i;
}
int i;
}
}
我明白了:
C.java:4: illegal generic type for instanceof
if ( !(o instanceof D) )
^
我还收到关于第 6 行的“未经检查的类型转换”警告。为什么? o
不是 通用类型——它只是一个普通的Object
。如何通过检查和强制转换为 D
的实例来正确实现 equals()
?
注意:显然,此代码示例是我实际代码的精简版。 C
和 D
的真正类要大得多,而 D
是 C 的
由其实现使用。private
内部类
仅供引用:真正的 D
确实使用了泛型参数 T
。
最佳答案
The o is not a generic type -- it's just a plain Object.
这不是问题。问题...以及这两个编译错误的根本原因...是D
是一个泛型类。它是泛型的,因为它是泛型类中的非静态嵌套类。它的完全限定名称是 some.pkg.C<T>.D
.
FYI: The real D does make use of the generic parameter T.
事实上它可以利用T
是什么让 D
一个泛型类。
无法使用的原因instanceof D
或 (D)
是泛型类型删除。基本上,运行时无法区分(比如说)C<String>.D
的类型。和 C<Integer>.D
.并且由于它不能这样做,它无法确定 instanceof D
应该返回 true
或 false
或者如果 (D)
应该成功还是抛出ClassCastException
.
一种解决方案是声明 D
作为静态的。但这不适用于您的“真正的 D”,因为静态类不能使用封闭类中的泛型类型参数。你的“仅供引用”说它会这样做。
另一种解决方案是实例化外部类 C
将 T
的实际类型传递给它作为 java.lang.Class<T>
实例。然后用这个Class
实例来根据需要实现运行时类型检查和强制转换。这可能会很困惑。
第三种解决方案是仔细分析代码并确定是否可以使用@SuppressWarning 注释来抑制“不安全强制转换”等警告。
What type erasure? 'o' is of type Object directly.
其实Object
是o
的已声明 类型多变的。实际对象很可能有其他类型,并且是 那个 类型(例如,如果它是 D
实例)将受到类型删除。
关于java - 为什么我会得到 "Illegal generic type for instanceof"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4001938/