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

深入理解 Java 巢狀類與內部類:四大類型完整解析

     編輯:Java 相關知識

基本概念

在一個類別內部定義另一個類別,稱為巢狀類。分為兩大類:

  • 靜態巢狀類:以 static 修飾。
  • 非靜態巢狀類:又稱內部類,包含三種形式:
    ① 成員內部類(直接在類別中定義)
    ② 方法內部類(在方法中定義)
    ③ 匿名內部類(無名稱,現場實例化)

靜態巢狀類

public class StaticTest {
    private static String name = "javaJohn";
    private String id = "X001";

    static class Person {
        private String address = "Chengdu";
        public String mail = "test@mail.com";

        public void display() {
            System.out.println(name); // 僅能存取外部靜態成員
            // System.out.println(id); // 編譯錯誤:無法存取非靜態成員
        }
    }

    public void printInfo() {
        Person p = new Person();
        p.display();
        System.out.println(p.mail); // 外部類可存取內部類私有成員
    }
}

特點:

  • 不持有外部類實例引用,無法直接存取非靜態成員。
  • 編譯產出 StaticTest$Person.class。
  • 僅在外部類作用域內可見。

成員內部類

public class Outer {
    int outer_x = 100;

    class Inner {
        public int y = 10;
        private int z = 9;
        public void display() { System.out.println("outer_x: " + outer_x); }
    }

    void test() {
        Inner inner = new Inner();
        inner.display();
        System.out.println(inner.z); // 外部類可存取內部類私有成員
    }

    class InnerTwo {
        Inner inner = new Inner();
        void show() { inner.display(); }
    }
}

規則:

  • 內部類持有外部類實例隱含引用,可直接存取外部所有成員(含 private)。
  • 外部類存取內部類成員需先建立內部類實例。
  • 同級內部類間需透過實例互訪。

方法內部類

class Outer {
    public void doSomething() {
        final int a = 10; // Java 8+ 可隱含 final
        class Inner {
            public void seeOuter() { System.out.println(a); }
        }
        new Inner().seeOuter(); // 僅能在方法內實例化
    }
}

限制:

  • 只能在定義該方法內實例化。
  • 無法存取方法的非 final 區域變數(生命週期不一致)。

匿名內部類

繼承式

Car car = new Car() {
    @Override public void drive() { System.out.println("Driving another car!"); }
};
car.drive(); // 實際執行匿名子類方法

實作介面式

Vehicle v = new Vehicle() {
    @Override public void drive() { System.out.println("Driving a car!"); }
};
v.drive(); // 實作介面的匿名類

參數式

b.doStuff(new Foo() {
    @Override public void foo() { System.out.println("foofy"); }
});

編譯產物與作用域

  • 所有內部類編譯後生成獨立 .class 檔,命名為 Outer$Inner.class、Outer$1.class(匿名類)。
  • 內部類屬於外部類成員,可用 private/protected 修飾。
  • 外部類以外程式碼無法直接實例化非靜態內部類,需先有外部類實例:new Outer().new Inner()。

總結

善用內部類可實現封裝、回調、事件監聽等模式。匿名內部類是 Java 7 以前實現函數式風格的主要手段,Java 8+ 建議改用 Lambda 表達式。

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