匿名内部类是Java中无需命名即可实现接口或继承抽象类的方式,适用于一次性、轻量级场景,如事件监听、线程启动、自定义排序等;其语法为new 接口/抽象类(参数) { 实现体 },要求基于已有类型、可访问外部final变量、不可定义静态成员(除static final外)。

匿名内部类是 Java 中一种简洁创建接口实现或抽象类子类的方式,不用单独定义类名,适合一次性、轻量级的场景。它常用于事件监听、线程启动、集合排序等需要快速传入行为逻辑的地方。
什么时候该用匿名内部类
当你只需要一个类的单次实例,且这个类的逻辑简单、不需复用、也不需在其他地方引用时,匿名类比单独写一个命名类更干净。典型场景包括:
- 为按钮添加点击监听(Swing/AWT)
- 启动一个只运行一次的线程
- 给
Arrays.sort()或TreeSet提供自定义比较器 - 实现回调接口(如 Retrofit 的 Callback、OkHttp 的 Callback)
语法结构与关键规则
匿名类本质是“一边定义一边实例化”,必须基于一个已存在的类型(接口或抽象类),不能是普通类。基本写法是:
new 接口名/抽象类名(构造参数) { 实现方法体 };注意几点:
- 如果父类是抽象类,构造参数要匹配其构造器(可带参)
- 如果实现的是接口,括号里不能写参数(接口无构造器)
- 匿名类中可以访问外部方法的 final 或 effectively final 局部变量
- 不能定义静态成员(除静态 final 常量外)
接口实现:以 Runnable 和 Comparator 为例
这是最常见用法。比如启动一个线程:
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("线程执行中");
}
}).start();
Java 8 后推荐用 Lambda 替代,但理解匿名类有助于读懂老代码和复杂逻辑(比如需要 this 引用或多个方法实现时)。再看排序:
String[] arr = {"banana", "apple", "cherry"};
Arrays.sort(arr, new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
return s1.length() - s2.length(); // 按长度排序
}
});
抽象类继承:以适配器模式简化监听
有些抽象类(如 MouseAdapter)只定义了空方法,方便子类按需重写。匿名类可精准覆盖所需方法:
component.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
System.out.println("双击触发");
}
<pre class="brush:php;toolbar:false;">@Override
public void mouseEntered(MouseEvent e) {
component.setBackground(Color.LIGHT_GRAY);
}});
这里没写 mousePressed 等其余方法,避免冗余空实现——比直接实现 MouseListener 接口更轻量。

















