[英]javac behavior change in JDK 7 regarding private member access
此代码使用javac JDK版本1.6.0_33-b03-424进行编译,但不使用javac JDK版本1.7.0_06进行编译。
public class Test {
private final int i = 0;
void test(Object o) {
if (getClass().isInstance(o)) {
System.out.println(getClass().cast(o).i);
}
}
}
javac输出是:
Test.java:6: error: i in Test is defined in an inaccessible class or interface
System.out.println(getClass().cast(o).i);
^
1 error
更改代码以将getClass.cast()
的结果存储在临时变量中允许程序无错误地编译。
这很容易解决,但我找不到JLS 7中这种更改的任何理由,或者在JDK 7发行说明中提到这样的更改。 提及有关泛型的类型参数的私有成员的访问更改,但这不适用于此处。
这是javac的回归吗? 它现在是否执行了以前没有强制执行的限制?
好吧,我对此感到困惑,我能冒险的唯一解释就是两件事的结合。
1_ getClass()
docs说如下:
实际的结果类型是
Class<? extends |X|>
Class<? extends |X|>
where|X|
是调用getClass
的表达式的静态类型的擦除。
2_ Java 7中引入的一个不兼容性是编译器不再允许访问类型变量的私有成员 。
因此,编译器不确定是否对基类或子类进行了转换,并且它阻止访问私有成员,因为如果将转换分配给子类,即使在原始父类中定义,它也是非法的,如以下示例所示:
class BaseTest {
private final int i = 1;
void test(Object o) {
if (getClass().isInstance(o)) {
TestAccess to = TestAccess.class.cast(o);
//System.out.println(to.i); // ERROR: i has private access in BaseTest
}
}
}
class TestAccess extends BaseTest{}
因此,我认为这是Java怪癖之一,因为规则在更复杂的例子中更有意义。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.