内部类应用场景
内部类不是炫技,正确使用能让代码更清晰、表达更自然。
场景速查
| 场景 | 推荐类型 | 原因 |
|---|---|---|
| 回调/事件监听 | 匿名内部类 | 一次性使用,代码简洁 |
| 工具类(逻辑归类) | 静态内部类 | 不需要外部状态,独立存在 |
| 迭代器/数据结构节点 | 静态内部类 | 与容器紧密关联,无实例依赖 |
| 需要访问外部实例 | 成员内部类 | 直接访问外部类成员 |
| 方法内临时使用 | 局部内部类 | 作用域限定,避免命名污染 |
事件监听(匿名内部类)
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);
}
}注意事项
- 不要滥用:如果内部类超过几百行,考虑拆分成独立类
- 保持简洁:内部类的存在应该是为了表达「一对一」的关系
- Lambda 优先:JDK 8+ 的函数式接口场景优先用 Lambda
- 内存泄漏警惕:非静态内部类持有外部引用,长期持有可能导致内存泄漏
- 静态 vs 非静态:不确定时,优先用静态内部类(无外部依赖,更安全)
