[英]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.