Java中內部類的分類及訪問權限控制

Java內部類分為四種類型及使用場景:1.成員內部類依賴外部類實例,可訪問所有成員;2.靜態內部類不依賴實例,只能訪問靜態成員;3.局部內部類定義在方法中,作用域受限;4.匿名內部類用于一次性的類實現。內部類會持有外部類引用,可能導致內存泄漏,解決方式包括使用靜態內部類、控制生命周期或手動置空。內部類適合緊密耦合的封裝場景,組合則適用于需要靈活解耦的設計。合理使用內部類不會顯著影響性能,但過多使用可能增加類加載開銷。

Java中內部類的分類及訪問權限控制

內部類是Java中一個挺有意思的特性,它允許你在一個類里面定義另一個類。這東西用好了,代碼結構會更清晰,封裝性也更強。但用不好,也容易把自己繞進去。

Java中內部類的分類及訪問權限控制

解決方案

Java中內部類的分類及訪問權限控制

Java中的內部類主要分為四種:成員內部類、靜態內部類、局部內部類和匿名內部類。每種內部類都有其特定的用途和訪問權限控制。

立即學習Java免費學習筆記(深入)”;

Java中內部類的分類及訪問權限控制

  • 成員內部類: 就像一個普通的成員變量一樣,它依賴于外部類的實例而存在。這意味著,只有先創建了外部類的實例,才能創建成員內部類的實例。成員內部類可以直接訪問外部類的所有成員,包括私有成員。

    class Outer {     private int outerVar = 10;      class Inner {         public void printOuterVar() {             System.out.println("Outer var: " + outerVar);         }     }      public void createInner() {         Inner inner = new Inner();         inner.printOuterVar();     } }  public class Main {     public Static void main(String[] args) {         Outer outer = new Outer();         outer.createInner();          // 另一種創建內部類的方式(需要先有外部類實例)         Outer.Inner inner = outer.new Inner();         inner.printOuterVar();     } }

    注意 outer.new Inner() 這種創建內部類實例的方式,必須先有外部類實例。

  • 靜態內部類: 顧名思義,它是用 static 關鍵字修飾的內部類。靜態內部類不依賴于外部類的實例,可以直接通過外部類名訪問。它只能訪問外部類的靜態成員。

    class Outer {     private static int outerStaticVar = 20;      static class Inner {         public void printOuterVar() {             System.out.println("Outer static var: " + outerStaticVar);         }     }      public static void createInner() {         Inner inner = new Inner();         inner.printOuterVar();     } }  public class Main {     public static void main(String[] args) {         Outer.createInner(); // 不需要外部類實例         Outer.Inner inner = new Outer.Inner(); // 直接通過外部類名訪問         inner.printOuterVar();     } }

    靜態內部類有點像外部類的一個靜態成員,但它仍然是一個類,可以擁有自己的成員變量和方法。

  • 局部內部類: 定義在方法或代碼塊中的類。它的作用范圍僅限于該方法或代碼塊。局部內部類不能使用訪問修飾符(如 public、private、protected),因為它不是外部類的成員。

    class Outer {     public void doSomething() {         class Inner {             public void printMessage() {                 System.out.println("Message from local inner class");             }         }          Inner inner = new Inner();         inner.printMessage();     } }  public class Main {     public static void main(String[] args) {         Outer outer = new Outer();         outer.doSomething();     } }

    局部內部類主要用于封裝一些只在特定方法中使用的邏輯。

  • 匿名內部類: 沒有名字的內部類。通常用于創建只需要使用一次的類。匿名內部類必須繼承一個類或實現一個接口

    interface MyInterface {     void doSomething(); }  public class Main {     public static void main(String[] args) {         MyInterface myInterface = new MyInterface() {             @Override             public void doSomething() {                 System.out.println("Doing something from anonymous inner class");             }         };          myInterface.doSomething();     } }

    匿名內部類經常與 Lambda 表達式一起使用,可以簡化代碼。

內部類如何影響Java程序的性能?

內部類本身并不會直接導致性能問題,關鍵在于如何使用。過多的內部類可能會增加類的數量,從而增加類加載的開銷。另外,成員內部類會持有外部類的引用,如果內部類的生命周期比外部類長,可能會導致內存泄漏。匿名內部類如果使用不當,可能會生成大量的類文件,也會影響性能。所以,需要根據實際情況權衡使用內部類的好處和潛在的性能影響。

內部類和組合有什么區別?什么時候應該使用哪種方式?

內部類和組合都是實現代碼重用和封裝的方式。內部類更側重于封裝,它允許內部類直接訪問外部類的成員,可以實現更緊密的耦合。組合更側重于解耦,通過接口或抽象類定義組件之間的關系,可以實現更靈活的擴展和維護。

什么時候應該使用內部類呢?當一個類只會被另一個類使用,并且需要訪問外部類的私有成員時,可以考慮使用內部類。例如,GUI編程中的事件監聽器,或者數據結構中的迭代器。什么時候應該使用組合呢?當需要實現更靈活的組件組合,并且組件之間不需要緊密的耦合時,應該使用組合。例如,設計一個圖形編輯器,可以使用組合的方式將不同的圖形組件組合在一起。

如何避免內部類導致的內存泄漏?

內存泄漏通常發生在成員內部類中,因為成員內部類會持有外部類的引用。如果內部類的生命周期比外部類長,可能會導致外部類無法被垃圾回收。避免內存泄漏的方法有以下幾種:

  1. 盡量使用靜態內部類,因為靜態內部類不持有外部類的引用。
  2. 如果必須使用成員內部類,確保內部類的生命周期不會超過外部類。
  3. 在不再需要內部類時,手動將其設置為 NULL,以便垃圾回收器可以回收它。
  4. 使用弱引用(WeakReference)來持有外部類的引用,這樣即使內部類持有外部類的引用,外部類也可以被垃圾回收。

? 版權聲明
THE END
喜歡就支持一下吧
點贊5 分享