Skip to content

内部类应用场景

内部类不是炫技,正确使用能让代码更清晰、表达更自然。

场景速查

场景推荐类型原因
回调/事件监听匿名内部类一次性使用,代码简洁
工具类(逻辑归类)静态内部类不需要外部状态,独立存在
迭代器/数据结构节点静态内部类与容器紧密关联,无实例依赖
需要访问外部实例成员内部类直接访问外部类成员
方法内临时使用局部内部类作用域限定,避免命名污染

事件监听(匿名内部类)

java
import java.awt.*;
import java.awt.event.*;

public class EventListenerDemo {

    public static void main(String[] args) {
        Frame frame = new Frame("Button Demo");
        Button button = new Button("Click Me");

        // 匿名内部类:事件监听
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("Button clicked!");
                System.exit(0);
            }
        });

        frame.add(button, BorderLayout.CENTER);
        frame.setSize(300, 200);
        frame.setVisible(true);
    }
}

迭代器模式(成员内部类)

java
import java.util.*;

public class IteratorPatternDemo {

    static class Collection {
        private Object[] items = {1, 2, 3, 4, 5};

        // 成员内部类:迭代器,依赖外部类实例
        public class Iterator {
            private int currentIndex = 0;

            public boolean hasNext() {
                return currentIndex < items.length;
            }

            public Object next() {
                return items[currentIndex++];
            }

            // 可以访问外部类成员
            public int remaining() {
                return items.length - currentIndex;
            }
        }

        public Iterator iterator() {
            return new Iterator();
        }
    }

    public static void main(String[] args) {
        Collection collection = new Collection();
        Collection.Iterator iter = collection.iterator();

        while (iter.hasNext()) {
            System.out.println(iter.next() + " (剩余: " + iter.remaining() + ")");
        }
    }
}

HashMap 节点(静态内部类)

JDK 源码中的经典用法:

java
public class HashMapDemo {

    // 静态内部类:节点,不依赖 HashMap 实例
    static class Node {
        private int hash;
        private String key;
        private String value;
        private Node next;

        Node(int hash, String key, String value, Node next) {
            this.hash = hash;
            this.key = key;
            this.value = value;
            this.next = next;
        }

        public String getKey() { return key; }
        public String getValue() { return value; }
        public Node getNext() { return next; }
    }

    public static void main(String[] args) {
        Node node1 = new Node(1, "name", "张三", null);
        Node node2 = new Node(2, "city", "北京", null);
        System.out.println(node1.getKey() + ": " + node1.getValue());
        System.out.println(node2.getKey() + ": " + node2.getValue());
    }
}

Builder 模式(静态内部类)

java
public class User {

    private final String name;
    private final int age;
    private final String email;

    // 静态内部类:Builder
    public static class Builder {
        private String name = "";
        private int age = 0;
        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);
        }
    }

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

    public static void main(String[] args) {
        User user = new User.Builder()
            .name("张三")
            .age(25)
            .email("zhang@example.com")
            .build();
        System.out.println(user.name + ", " + user.age);
    }
}

注意事项

  1. 不要滥用:如果内部类超过几百行,考虑拆分成独立类
  2. 保持简洁:内部类的存在应该是为了表达「一对一」的关系
  3. Lambda 优先:JDK 8+ 的函数式接口场景优先用 Lambda
  4. 内存泄漏警惕:非静态内部类持有外部引用,长期持有可能导致内存泄漏
  5. 静态 vs 非静态:不确定时,优先用静态内部类(无外部依赖,更安全)

基于 VitePress 构建