Java 內部類別 (Inner Class)

內部類別是定義在另一個類別內部的類別,可以存取外部類別的成員,包括私有成員。

成員內部類別

public class Outer {
    private String message = "Hello";

    // 成員內部類別
    public class Inner {
        public void display() {
            // 可以存取外部類別的私有成員
            System.out.println(message);
        }
    }
}

// 使用
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
inner.display();  // Hello

存取外部類別

public class Outer {
    private int value = 10;

    public class Inner {
        private int value = 20;

        public void show() {
            int value = 30;
            System.out.println(value);             // 30(區域變數)
            System.out.println(this.value);        // 20(內部類別)
            System.out.println(Outer.this.value);  // 10(外部類別)
        }
    }
}

靜態內部類別

public class Outer {
    private static String staticMsg = "Static";
    private String instanceMsg = "Instance";

    // 靜態內部類別
    public static class StaticInner {
        public void display() {
            System.out.println(staticMsg);  // 可以存取靜態成員
            // System.out.println(instanceMsg);  // 錯誤!不能存取實例成員
        }
    }
}

// 使用(不需要外部類別實例)
Outer.StaticInner inner = new Outer.StaticInner();
inner.display();

區域內部類別

public class Outer {
    public void method() {
        final String localVar = "Local";

        // 區域內部類別(方法內部)
        class LocalInner {
            public void display() {
                System.out.println(localVar);  // 只能存取 final 或 effectively final 的區域變數
            }
        }

        LocalInner inner = new LocalInner();
        inner.display();
    }
}

比較

類型位置存取外部建立方式
成員內部類別類別內所有成員outer.new Inner()
靜態內部類別類別內只有靜態new Outer.StaticInner()
區域內部類別方法內final 變數方法內建立

實用範例

Builder 模式

public class User {
    private final String name;
    private final int age;
    private final String email;

    private User(Builder builder) {
        this.name = builder.name;
        this.age = builder.age;
        this.email = builder.email;
    }

    public static class Builder {
        private String name;
        private int age;
        private String email;

        public Builder name(String name) {
            this.name = name;
            return this;
        }

        public Builder age(int age) {
            this.age = age;
            return this;
        }

        public Builder email(String email) {
            this.email = email;
            return this;
        }

        public User build() {
            return new User(this);
        }
    }
}

// 使用
User user = new User.Builder()
    .name("Alice")
    .age(25)
    .email("alice@example.com")
    .build();

Iterator 實作

public class MyList<T> {
    private Object[] elements;
    private int size;

    public Iterator<T> iterator() {
        return new MyIterator();
    }

    private class MyIterator implements Iterator<T> {
        private int index = 0;

        @Override
        public boolean hasNext() {
            return index < size;
        }

        @Override
        @SuppressWarnings("unchecked")
        public T next() {
            return (T) elements[index++];
        }
    }
}

重點整理

  • 成員內部類別:可存取外部類別所有成員
  • 靜態內部類別:只能存取靜態成員,不依賴外部實例
  • 區域內部類別:定義在方法內,只能存取 final 變數
  • 使用 Outer.this 存取外部類別實例
  • 靜態內部類別常用於 Builder 模式