Java 为什么我会得到;instanceof“的泛型类型非法;?

Java 为什么我会得到;instanceof“的泛型类型非法;?,java,generics,Java,Generics,鉴于: 我还收到一条关于第6行的“未经检查的演员阵容”警告。为什么?o不是泛型类型——它只是一个普通的对象。如何通过检查并强制转换到D的实例来正确实现equals() 注意:显然,这个代码示例是我实际代码的精简版本。C和D的实际类要大得多,D是其实现使用的C的private内部类 仅供参考:realD确实使用了泛型参数T如果将内部类设置为静态,则代码编译良好 例: 读读区别 您也可以尝试o.getClass()!=D.class(当然,在防止o为空之后) o不是泛型类型——它只是一个普通对象 这

鉴于:

我还收到一条关于第6行的“未经检查的演员阵容”警告。为什么?
o
不是泛型类型——它只是一个普通的
对象
。如何通过检查并强制转换到
D
的实例来正确实现
equals()

注意:显然,这个代码示例是我实际代码的精简版本。
C
D
的实际类要大得多,
D
是其实现使用的
C
private
内部类


仅供参考:real
D
确实使用了泛型参数
T

如果将内部类设置为静态,则代码编译良好

例:

读读区别

您也可以尝试
o.getClass()!=D.class
(当然,在防止o为空之后)

o不是泛型类型——它只是一个普通对象

这不是问题所在。问题是。。。这两个编译错误的根本原因。。。就是说
D
是一个泛型类。它是泛型的,因为它是泛型类中的非静态嵌套类。它的完全限定名是
some.pkg.C.D

仅供参考:实数D确实使用了通用参数T

它可以利用
T
这一事实使得
D
成为一个泛型类

无法使用D或D实例的原因是泛型类型擦除。基本上,运行时无法区分(例如)
C.D
C.D
的类型。由于它不能做到这一点,它无法确定D的实例是否应该返回
true
false
,或者
(D)
是否应该成功或抛出
ClassCastException

一种解决方案是将
D
声明为静态。但这对“real D”不起作用,因为静态类不能使用封闭类中的泛型类型参数。你的“通知”上说是这样的

另一个解决方案是实例化外部类
C
,将
T
的实际类型作为
java.lang.class
实例传递给它。然后使用这个
实例根据需要执行运行时类型检查和强制转换。这可能会很混乱

第三种解决方案是仔细分析代码,并确定@SuppressWarning注释抑制“不安全强制转换”etc警告是否安全

什么类型的擦除?”o'直接属于Object类型

实际上,
Object
o
变量的声明类型。实际对象很可能具有其他类型,并且正是该类型(例如,如果它是
D
实例)将经历类型擦除

private static class D{...}

似乎在这里起作用。

@StephenC是正确的,因为问题在于
D
表示
C.D
,这是一种参数化类型。解决方案是使用原始类型或通配符参数化类型:

D.class.isInstance(o)

if(!(C.D的o实例))

你试过instanceof C.D而不是instanceof D吗?我只想指出,给出的例子是错误的。@Evan:这很有效。但是为什么需要资格认证呢?这可能是一个编译器错误()。@Evan:很好的链接——谢谢!但我不认为这是一个错误,如果你阅读所有的评论。。。这只是Java泛型的一个奇怪结果。我知道非静态类和静态嵌套类之间的区别。在这种情况下,我需要它是非静态的。如果将嵌套类设为静态,则无法使用泛型参数t。o.getClass()和D.class比较如何?您不知道它们是同一个参数化类型,但我不确定您是否能够可靠地使用类型擦除来实现这一点。什么类型的擦除?”o'直接属于Object类型。假设o'指向某个类型D,就无法判断它是D,而不是D。因此,如果我是a D,而o真的是a D,那么最好的说法是它们都是a D。但它是一个普通的对象,可以是任何对象:D、整数、可运行的,等等。我不明白为什么类型很重要。
private static class D{...}
D.class.isInstance(o)
if ( !(o instanceof C.D) )
if ( !(o instanceof C<?>.D) )