簡體   English   中英

關於私有成員訪問的JDK 7中的javac行為更改

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM