java 为什么我会得到“instanceof 的非法泛型类型”?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4001938/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why do I get "Illegal generic type for instanceof"?
提问by Paul J. Lucas
Given:
鉴于:
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;
}
}
I get:
我得到:
C.java:4: illegal generic type for instanceof
if ( !(o instanceof D) )
^
I also get an "unchecked cast" warning about line 6. Why? The o
is nota generic type -- it's just a plain Object
. How can I correctly implement equals()
by both checking for and casting to an instance of D
?
我还收到关于第 6 行的“未经检查的强制转换”警告。为什么?该o
是不是一个泛型类型-它只是一个普通的Object
。如何equals()
通过检查和强制转换为 的实例来正确实现D
?
Note: Obviously, this code example is a whittled-down version of my actual code. The real classes for C
and D
are much larger and D
is a private
inner class of C
used by its implementation.
注意:显然,此代码示例是我实际代码的精简版本。真正的类C
和D
都大得多,D
是一个private
内部类的C
其实现中使用。
FYI: The real D
does make use of the generic parameter T
.
仅供参考:真实D
确实使用了泛型参数T
。
回答by Stephen C
The o is not a generic type -- it's just a plain Object.
o 不是泛型类型——它只是一个普通的对象。
That's not the problem. The problem ... and the root cause of both compilation errors ... is that D
is a generic class. And it is generic because it is a non-static nested class in a generic class. Its fully qualified name would be some.pkg.C<T>.D
.
那不是问题。问题......以及两个编译错误的根本原因......是这D
是一个泛型类。它是泛型的,因为它是泛型类中的非静态嵌套类。它的完全限定名称是some.pkg.C<T>.D
.
FYI: The real D does make use of the generic parameter T.
仅供参考:真正的 D 确实使用了通用参数 T。
And the fact that it couldmake use of T
is what makes D
a generic class.
它可以利用的事实T
是什么造就D
了泛型类。
The reason that you cannot use instanceof D
or (D)
is generic type erasure. Basically, the runtime cannot distinguish between the types of (say) C<String>.D
and C<Integer>.D
. And since it cannot do that, it cannot determine if instanceof D
should return true
or false
or if (D)
should succeed or throw ClassCastException
.
不能使用的原因instanceof D
或者(D)
是泛型类型擦除。基本上,运行时无法区分 (say)C<String>.D
和C<Integer>.D
. 而且,由于它不能做到这一点,就不能确定是否instanceof D
应该返回true
或者false
或者(D)
应该成功或抛出ClassCastException
。
One solution would be to declare D
as static. But that will not work with your "real D" because a static class cannot make use of a generic type parameter from the enclosing class(es). Your "FYI" says that it does that.
一种解决方案是声明D
为静态。但这不适用于您的“真正的 D”,因为静态类不能使用来自封闭类的泛型类型参数。你的“仅供参考”说它这样做了。
Another solution is to instantiate the outer class C
passing it the actual type of T
as a java.lang.Class<T>
instance. Then use this Class
instance to implement the runtime type checks and casts as required. This is likely to be messy.
另一种解决方案是实例化外部类,C
将其T
作为java.lang.Class<T>
实例的实际类型传递给它。然后根据需要使用此Class
实例实现运行时类型检查和强制转换。这很可能是混乱的。
The third solution is to carefullyanalyze the code and determine if it is safe to a @SuppressWarning annotations to suppress the "unsafe cast" etc warnings.
第三种解决方案是仔细分析代码并确定使用@SuppressWarning 注释来抑制“不安全转换”等警告是否安全。
What type erasure? 'o' is of type Object directly.
什么类型的擦除?'o' 直接是 Object 类型。
Actually Object
is the declaredtype of the o
variable. The actual object will most likely have some other type, and it is thattype that (if it is a D
instance for example) will have been subjected to type erasure.
实际上Object
是变量的声明类型o
。实际对象很可能具有其他类型,并且正是该类型(D
例如,如果它是一个实例)将受到类型擦除。
回答by newacct
@StephenC is right in that the problem is that D
means C<T>.D
, which is a parameterized type. The solution is to use the raw type or the wildcard-parameterized type:
@StephenC 是对的,因为问题在于D
意味着C<T>.D
,它是一个参数化类型。解决方案是使用原始类型或通配符参数化类型:
if ( !(o instanceof C.D) )
or
或者
if ( !(o instanceof C<?>.D) )
回答by Stefan Kendall
回答by jederik
D.class.isInstance(o)
seems to work here.
似乎在这里工作。