下面是一些使用Java6编译但不能在Java7中编译的代码的简单示例。
public class Test<T extends Test> {
private final int _myVar;
public Test(int myVar) {
_myVar = myVar;
}
public int get(TestContainer<T> container){
T t = container.get();
return t._myVar;
}
private static class TestContainer<T extends Test> {
private final T _test;
private TestContainer(T test) {
_test = test;
}
public T get(){
return _test;
}
}
}
在Java7中,它无法在get(TestContainer<T> container)
方法中编译,错误如下:
错误:_myVar在测试中具有私有访问权限
我不明白为什么它不再编译了--在我看来它应该编译。变量t
的类型为T
,它必须扩展Test
。它试图从类Test
中访问Test
实例的字段_myVar
。
实际上,如果我将方法get(TestContainer<T> container)
更改为以下内容,它将进行编译(没有任何警告):
public int get(TestContainer<T> container){
Test t = container.get();
return t._myVar;
}
我已经用谷歌搜索了甲骨文的bug数据库,但没有找到任何关于这个的东西……
发布于 2012-05-29 20:16:11
§4.9 ...则交集类型具有与类类型相同的成员(§8),具有空体、直接超类Ck和直接超接口T1',...,Tn',在出现交集类型的同一个包中声明。
根据我对JLS部分的理解,您使用类型变量<T extends Test>
的情况创建了以下交集:
package <the same as of Test>;
class I extends Test {}
因此,当您访问交集类型T
的成员时,实际上访问的是交集类型I
的成员。由于子类型从不继承私有成员,因此访问此类成员会因编译错误而失败。另一方面,允许访问package-private (默认)和受保护的成员,因为交叉点是
...在出现交叉点类型的同一个包中声明。
发布于 2012-05-29 11:46:18
请参阅@pingw33n的注释以获得答案,但修复此问题的方法是删除嵌套类上的泛型参数。除非你有一个内部和外部T可能不同的用例,否则它们是多余的。他们所做的一切都是在制造这种悲痛。
发布于 2014-03-15 06:27:44
一种解决方法是将泛型实例强制转换为声明私有字段的具体超类型,例如
public int get(TestContainer<T> container){
T t = container.get();
return ((Test) t)._myVar;
}
https://stackoverflow.com/questions/10782876
复制相似问题