亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Oracle Java 教程 - 靜態類 - 教程中可能出現的錯誤

Oracle Java 教程 - 靜態類 - 教程中可能出現的錯誤

瀟瀟雨雨 2021-08-25 17:19:31
我是 Java 新手,從 Oracle Java 教程學習 Java。我現在正在學習嵌套類、靜態類和內部類。我發現以下解釋似乎很奇怪,我認為這是錯誤的。來自:https : //docs.oracle.com/javase/tutorial/java/javaOO/nested.html嵌套類是其封閉類的成員。非靜態嵌套類(內部類)可以訪問封閉類的其他成員,即使它們被聲明為私有。靜態嵌套類無權訪問封閉類的其他成員最后一句“靜態嵌套類無法訪問封閉類的其他成員”很奇怪,但可能指的是實例成員,說靜態類就像一個靜態方法,無法訪問實例變量。但下一個注釋更奇怪:注意:靜態嵌套類與其 外部類(和其他類)的實例成員交互,就像任何其他頂級類一樣。實際上,靜態嵌套類在行為上是一個頂層類,為了方便打包,它嵌套在另一個頂層類中。這看起來很奇怪,因為它意味著靜態類不能訪問外部類的私有實例成員。我編寫了以下編譯和運行的代碼,并演示了靜態類可以訪問外部實例私有變量。public class A {    private int x;    static private int y;    static public class B{        static void doSomething(){            y++;            System.out.println("y is now " + y );        }        static void doSomethingElse(A a)        {            a.x++;            System.out.println("a.x is " + a.x );        }    }}// ------public class Main {    public static void main(String[] args){        A a = new A();        A.B b = new A.B();        b.doSomething();        b.doSomethingElse(a);    }}這是教程中的錯誤,還是我可能不太理解?謝謝
查看完整描述

2 回答

?
慕雪6442864

TA貢獻1812條經驗 獲得超5個贊

這是教程中的錯誤,還是我可能不太理解?

你完全理解。教程頁面充其量是誤導性的。

這里有兩個不同的概念:

  1. 您是否有權訪問 Java訪問控制規則(例如,私有、包私有、受保護、公共)內的事物。

  2. “靜態”的含義。“內部”嵌套類的實例總是與封閉類的實例相關聯(在內部類的隱藏實例字段中存儲對封閉類實例的引用)?!办o態”嵌套類沒有。

教程頁面混淆了這兩個概念。

嵌套類是其封閉類的成員。

是的。

非靜態嵌套類(內部類)可以訪問封閉類的其他成員,即使它們被聲明為私有。靜態嵌套類無權訪問封閉類的其他成員。

不。

通過自己提供實例,您會看到靜態類確實可以訪問封閉類的成員,包括私有實例字段,因此為什么a.x++;在您的示例中進行編譯。這就是訪問。

通過使用“訪問”和“私有”這兩個詞,該段落強烈暗示它是在 Java 語言規范中給出的定義中討論訪問控制。但事實并非如此。它只是試圖解釋概念#2,關于封閉類的實例如何與嵌套類相關聯。即便如此,它仍然是錯誤的,因為靜態嵌套類當然可以訪問封閉類的靜態成員,而段落說他們沒有。寫那個頁面的人很草率。

注意:靜態嵌套類與其外部類(和其他類)的實例成員交互,就像任何其他頂級類一樣。實際上,靜態嵌套類在行為上是一個頂層類,為了方便打包,它嵌套在另一個頂層類中。

這一段還在講靜態是什么意思。雖然它有可能被誤解,但它并不試圖說明訪問控制。


這是正確的訪問控制規則,由JLS§6.6.1 – Determining Accessibility 給出:

[如果] 聲明了成員或構造函數private,當且僅當它出現在包含成員或構造函數聲明的頂級類(第 7.6 節)的主體內時,才允許訪問 [..]。

該定義出奇地短,但它涵蓋了此處相關的所有內容。

這意味著所有嵌套類(因為它們“在頂級類的主體內”)都可以訪問封閉類的所有成員和構造函數,無論嵌套類是靜態類還是實例類,也不管嵌套類是靜態類還是實例類訪問的東西是靜態的或實例。

此外,所有嵌套類還可以訪問同一頂級類中所有其他嵌套類的所有成員和構造函數。

頂級類可以訪問嵌套在其中的所有類的所有成員和構造函數。

我引用的JLS那句話是指private訪問。但是如果成員或構造函數不是private,那么它的訪問級別只能更寬松,至少包訪問,并且包含在同一頂級類型中的類也不可避免地在同一個包中,因此它們可以相互訪問即使沒有特殊處理。

基本上,頂級(非封閉)類及其中的所有內容都構成了一個nest。原則上,該巢中的所有內容都可以訪問其中的其他所有內容。如果它是一個實例成員,您還需要先以某種方式獲取一個實例,但這總是正確的。


查看完整回答
反對 回復 2021-08-25
?
拉莫斯之舞

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)方法參數中。


靜態嵌套和獨立的主要區別在于前者,嵌套類,可以訪問外部類的私有成員,而獨立則沒有。也許這就是你困惑的根源。


查看完整回答
反對 回復 2021-08-25
  • 2 回答
  • 0 關注
  • 189 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號