Moh*_*nan 3 java generics intellij-idea
看代码
public class AdnanTestClass<T> {
public void doForTest(Object o){
if (o instanceof TestInnerClass){
}
}
private class TestInnerClass{
}
}
Run Code Online (Sandbox Code Playgroud)
这段代码在doForTest
方法中给出了编译时错误.它说非法的仿制药类型.
如果我用这样的外类限定内部类
if (o instanceof AdnanTestClass.TestInnerClass){
}
Run Code Online (Sandbox Code Playgroud)
这个编译完全没问题.
if (o instanceof TestInnerClass)
如果我<T>
从我的班级声明中删除也会有效.
我不确定我在这里失踪了什么.是否存在符合外部资格的潜在问题.有人可以指出吗?我用intellij idea 14和Java 8做了这个测试.
Roh*_*ain 11
来自JLS§15.20.2:
如果在instanceof运算符之后提到的ReferenceType不表示可重新生成的引用类型(第4.7节),则为编译时错误.
现在,您的第一个代码:
if (o instanceof TestInnerClass)
Run Code Online (Sandbox Code Playgroud)
相当于:
if (o instanceof AdnanTestClass<T>.TestInnerClass)
Run Code Online (Sandbox Code Playgroud)
但是,由于AdnanTestClass<T>
不可再生(参见JLS§4.7),
AdnanTestClass<T>.TestInnerClass
也不可再生,因此这不是一个有效的表达.该JLS部分的相关引用:
例如,如果泛型类
X<T>
具有泛型成员类Y<U>
,则该类型X<?>.Y<?>
是可重新生成的,因为它X<?>
是可重新生成的并且Y<?>
是可恢复的.该类型X<?>.Y<Object>
不可再生,因为Y<Object>
不可再生.
相反,如果您将其更改为:
// unbounded wildcard
if (o instanceof AdnanTestClass<?>.TestInnerClass)
// or, raw type
if (o instanceof AdnanTestClass.TestInnerClass)
Run Code Online (Sandbox Code Playgroud)
这将是可以回收的,因此是有效的表达.