参见代码
public class AdnanTestClass<T> {
public void doForTest(Object o){
if (o instanceof TestInnerClass){
}
}
private class TestInnerClass{
}
}
这段代码在doForTest
方法中给出了编译时错误。它说非法的仿制药类型。
如果我用这样的外部类来限定内部类
if (o instanceof AdnanTestClass.TestInnerClass){
}
这个编译完全没问题。
如果我从类声明中删除if (o instanceof TestInnerClass)
, <T>
也可以。
我不确定我在这里失踪了什么。是否存在符合外部资格的潜在问题。有人可以指出吗?我用intellij idea 14和Java 8做了这个测试。
答案 0 :(得分:11)
来自JLS §15.20.2:
如果在之后提到的ReferenceType是一个编译时错误 instanceof运算符不表示可重新生成的引用类型 (§4.7)。
现在,您的第一个代码:
if (o instanceof TestInnerClass)
相当于:
if (o instanceof AdnanTestClass<T>.TestInnerClass)
但是,由于AdnanTestClass<T>
无法恢复(请参阅JLS §4.7),
AdnanTestClass<T>.TestInnerClass
也不可恢复,因此这不是一个有效的表达式。该JLS部分的相关引用:
例如,如果泛型类
X<T>
具有泛型成员类Y<U>
,然后类型X<?>.Y<?>
可以恢复,因为X<?>
是。{1}} 可以恢复,Y<?>
可以恢复。类型X<?>.Y<Object>
不是 可以回复,因为Y<Object>
不可再生。
相反,如果您将其更改为:
// unbounded wildcard
if (o instanceof AdnanTestClass<?>.TestInnerClass)
// or, raw type
if (o instanceof AdnanTestClass.TestInnerClass)
这将成为可以恢复的,因此是有效的表达。
答案 1 :(得分:3)
在您的情况下,o instanceof TestInnerClass
语法实际上是o instanceof AdnanTestClass<T>.TestInnerClass
的简写,但由于类型参数(<T>
部分)在运行时被删除,因此该短手不再有效,因此Java编译器为您提供错误,并要求显式删除类型参数。
以下是有关泛型类型擦除的更多信息:http://docs.oracle.com/javase/tutorial/java/generics/erasure.html
答案 2 :(得分:2)
此
if (o instanceof TestInnerClass){
等于
if (o instanceof AdnanTestClass<T>.TestInnerClass){
因此,如果instanceof
没有明确说明外部课程T
是什么,则无法正确检查T
。
你的第二段代码忽略private class TestInnerClass<T> {
,它是未定义的,但是对于内部类,它已经是明确的
我认为你可以这样解决:
{{1}}