首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 內部類深度解析:五大類型、訪問規則與實戰示例

     編輯:Java 相關知識

內部類是 Java 中一項強大卻常被誤解的特性。本文通過五個遞進式實例,系統講解成員內部類、靜態內部類、私有內部類、方法局部內部類及匿名內部類的語法結構、訪問權限、編譯產物與典型應用場景,助你徹底掌握這項核心語法。

核心概念:什麼是內部類?

內部類定義在另一個類的內部,邏輯上隸屬於外部類。它能無條件訪問外部類所有成員 (含 private),這是其存在的唯一核心優勢——如同心臟直接泵血而無需醫生抽血。

編譯後生成獨立 .class 文件,命名規則:OuterClass$InnerClass.class,`$` 符號代表層級關系。

實例 1:成員內部類基本結構

class Out {
    private int age = 12;
    class In {
        public void print() { System.out.println(age); }
    }
}
public class Demo {
    public static void main(String[] args) {
        Out.In in = new Out().new In(); // 必須先有外部類實例
        in.print(); // 輸出 12
    }
}

關鍵點:

  • 創建語法:OuterClass.InnerClass obj = new OuterClass().new InnerClass();
  • 內部類實例隱式持有外部類實例引用 (OuterClass.this),故不能在靜態上下文直接實例化非靜態內部類。

實例 2:變量訪問優先級與 this 限定

class Out {
    private int age = 12;
    class In {
        private int age = 13;
        public void print() {
            int age = 14;
            System.out.println("局部變量:" + age);           // 14
            System.out.println("內部類變量:" + this.age);     // 13
            System.out.println("外部類變量:" + Out.this.age); // 12
        }
    }
}

訪問規則口訣:局部 > 內部類成員 > 外部類成員。同名時需用 this 或 OuterClass.this 顯式限定。

實例 3:靜態內部類

class Out {
    private static int age = 12;
    static class In {
        public void print() { System.out.println(age); }
    }
}
public class Demo {
    public static void main(String[] args) {
        Out.In in = new Out.In(); // 無需外部類實例
        in.print(); // 12
    }
}

特性:

  • 不持有外部類實例引用,只能訪問外部類 static 成員。
  • 可直接用 OuterClass.InnerClass 實例化,行為類似頂層類,常用於工具類、Builder 模式、單例模式靜態內部類寫法。

實例 4:私有內部類

class Out {
    private int age = 12;
    private class In { // 僅外部類可見
        public void print() { System.out.println(age); }
    }
    public void outPrint() { new In().print(); }
}
public class Demo {
    public static void main(String[] args) {
        Out out = new Out();
        out.outPrint(); // 12
        // new Out().new In(); // 編譯錯誤:In 為 private
    }
}

用途:完全封裝實現細節,外部不可直接實例化,只能通過外部類提供的方法間接使用,類似「心臟只能由身體控制」。

實例 5:方法局部內部類

class Out {
    private int age = 12;
    public void print(final int x) {
        class In { // 定義在方法內
            public void inPrint() {
                System.out.println(x); // 必須 final 或 effectively final
                System.out.println(age);
            }
        }
        new In().inPrint();
    }
}
public class Demo {
    public static void main(String[] args) {
        new Out().print(3); // 輸出 3, 12
    }
}

限制:

  • 只能訪問方法參數為 final (Java 8+ 允許 effectively final) 的局部變量。
  • 作用域僅限方法內部,外部不可見,極大縮小可見範圍。
  • 常用於線程類、比較器等一次性邏輯封裝。

補充:匿名內部類 (Anonymous Inner Class)

無名稱、繼承類/實現接口、現場創建實例:

new Thread(new Runnable() {
    @Override public void run() { System.out.println("Running..."); }
}).start();

Java 8+ 推薦用 Lambda 替代函數式接口匿名類,代碼更簡潔。

總結與最佳實踐

類型修飾符訪問外部實例成員需外部實例典型場景
成員內部類可加 private/protected是 (含非 static)是邏輯強綁定、迭代器、事件監聽
靜態內部類static僅 static 成員否工具類、Builder、單例、緩存節點
方法局部類無 (隱式 final)是 (含非 static)是一次性邏輯、線程任務、比較器
匿名內部類無是 (含非 static)是函數式接口實現、事件回調 (Java 7-)

合理使用內部類可提高封裝性、減少類文件數量、實現閉包效果。但濫用會導致代碼難讀、持有外部引用引發內存洩漏 (如長生命周期匿名類持有 Activity)。原則:優先考慮靜態內部類,其次成員內部類,慎用局部/匿名類,必要時改用 Lambda 或獨立頂層類。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved