2 回答

TA貢獻1812條經驗 獲得超5個贊
這是教程中的錯誤,還是我可能不太理解?
你完全理解。教程頁面充其量是誤導性的。
這里有兩個不同的概念:
您是否有權訪問 Java訪問控制規則(例如,私有、包私有、受保護、公共)內的事物。
“靜態”的含義。“內部”嵌套類的實例總是與封閉類的實例相關聯(在內部類的隱藏實例字段中存儲對封閉類實例的引用)?!办o態”嵌套類沒有。
教程頁面混淆了這兩個概念。
嵌套類是其封閉類的成員。
是的。
非靜態嵌套類(內部類)可以訪問封閉類的其他成員,即使它們被聲明為私有。靜態嵌套類無權訪問封閉類的其他成員。
不。
通過自己提供實例,您會看到靜態類確實可以訪問封閉類的成員,包括私有實例字段,因此為什么a.x++;
在您的示例中進行編譯。這就是訪問。
通過使用“訪問”和“私有”這兩個詞,該段落強烈暗示它是在 Java 語言規范中給出的定義中討論訪問控制。但事實并非如此。它只是試圖解釋概念#2,關于封閉類的實例如何與嵌套類相關聯。即便如此,它仍然是錯誤的,因為靜態嵌套類當然可以訪問封閉類的靜態成員,而段落說他們沒有。寫那個頁面的人很草率。
注意:靜態嵌套類與其外部類(和其他類)的實例成員交互,就像任何其他頂級類一樣。實際上,靜態嵌套類在行為上是一個頂層類,為了方便打包,它嵌套在另一個頂層類中。
這一段還在講靜態是什么意思。雖然它有可能被誤解,但它并不試圖說明訪問控制。
這是正確的訪問控制規則,由JLS§6.6.1 – Determining Accessibility 給出:
[如果] 聲明了成員或構造函數
private
,當且僅當它出現在包含成員或構造函數聲明的頂級類(第 7.6 節)的主體內時,才允許訪問 [..]。
該定義出奇地短,但它涵蓋了此處相關的所有內容。
這意味著所有嵌套類(因為它們“在頂級類的主體內”)都可以訪問封閉類的所有成員和構造函數,無論嵌套類是靜態類還是實例類,也不管嵌套類是靜態類還是實例類訪問的東西是靜態的或實例。
此外,所有嵌套類還可以訪問同一頂級類中所有其他嵌套類的所有成員和構造函數。
頂級類可以訪問嵌套在其中的所有類的所有成員和構造函數。
我引用的JLS那句話是指private
訪問。但是如果成員或構造函數不是private
,那么它的訪問級別只能更寬松,至少包訪問,并且包含在同一頂級類型中的類也不可避免地在同一個包中,因此它們可以相互訪問即使沒有特殊處理。
基本上,頂級(非封閉)類及其中的所有內容都構成了一個nest。原則上,該巢中的所有內容都可以訪問其中的其他所有內容。如果它是一個實例成員,您還需要先以某種方式獲取一個實例,但這總是正確的。

TA貢獻1820條經驗 獲得超10個贊
這是教程中的錯誤,還是我不太了解某些內容?
錯誤在于您的理解,而教程是正確的。在嵌套的靜態類中沒有任何地方可以直接操作外部類的實例字段。我說的是沒有附加實例的這些字段——如果沒有x附加到A實例,你就無法直接操作。
所以你可以這樣做:
static void doSomethingElse(A a) {
a.x++; // x is part of the A instance passed into a parameter
System.out.println("a.x is " + a.x );
}
但你不能這樣做:
static void doSomethingElse2() {
x++;
System.out.println("x is " + x );
}
如果B是靜態嵌套或獨立的非嵌套類,則此代碼將相同。
你問:
“靜態嵌套類與其外部類的實例成員交互,就像任何其他頂級類一樣”?
完全如上所示——非靜態嵌套類可以直接與a字段交互(如圖doSomethingElse2()所示),而無需支持A實例,而靜態嵌套類和獨立類都不能。它們都需要單獨的 A 實例,此處將其傳遞到您的doSomethingElse(A a)方法參數中。
靜態嵌套和獨立的主要區別在于前者,嵌套類,可以訪問外部類的私有成員,而獨立則沒有。也許這就是你困惑的根源。
添加回答
舉報