Java 內部類別實例持有外部類別參考(OuterClass.this),可存取外部類別所有成員(含 private)。但外部類別、同套件其他類別、不同套件類別、繼承類別對內部類別的可見性有何差異?本文透過完整程式碼實測四種內部類別(private、default、protected、public)在四種情境下的存取規則。
外部類別 Out 定義四種內部類別,皆實作 InMethod 介面(含 public_method())。每個內部類別擁有四種可見性的欄位與方法。Out 提供 getXxxIn() 回傳內部類別實例。
兩種建立方式:
new Out().new PrivateIn()out.getPrivateIn()結果:外部類別可建立所有內部類別實例,並存取其所有成員(含 private 欄位/方法)。內部類別對建立它的外部類別實例完全可見。
out.new Inner()private 內部類別:編譯錯誤,型別不可見default、protected、public:可建立實例,但無法存取內部類別的 private 成員out.getPrivateIn()PrivateIn 時,同樣編譯錯誤(型別不可見)InMethod ref = out.getPrivateIn():可呼叫 public_method()out.new PublicIn() 或 out.getPublicIn():僅能存取 public 內部類別的 public 成員InMethod ref = out.getXxxIn():可呼叫所有內部類別的 public_method()extend.new ProtectedIn():型別可見,但建構子不可見(編譯錯誤)extend.getProtectedIn():可取得實例,但僅能存取 public 成員結論:protected 內部類別不受外部類別繼承關係影響,其建構子與成員存取權遵循一般 protected 規則(同套件可見、子類別可見型別但不可實例化)。
| 存取者 | private 內部類別 | default 內部類別 | protected 內部類別 | public 內部類別 |
|---|---|---|---|---|
| 外部類別 | 完全可見 | 完全可見 | 完全可見 | 完全可見 |
| 同套件類別 | 型別不可見,介面參考可呼叫 public 方法 | 型別可見,無法存取 private 成員 | 型別可見,無法存取 private 成員 | 型別可見,無法存取 private 成員 |
| 不同套件類別 | 型別不可見,介面參考可呼叫 public 方法 | 型別不可見 | 型別不可見 | 型別可見,僅能存取 public 成員 |
| 不同套件子類別 | 型別不可見,介面參考可呼叫 public 方法 | 型別不可見 | 型別可見,建構子不可見,僅能存取 public 成員 | 型別可見,僅能存取 public 成員 |
private 內部類別對外完全隱藏,只能透過外部類別方法以介面型別回傳protected 內部類別的建構子不可被子類別呼叫,這與一般 protected 方法行為不同