匿名内部类可直接实现接口,语法为new 接口名() {…},需实现全部抽象方法;适用于runnable、comparator等场景,但注意内存泄漏,java 8后单方法接口优先用lambda。

直接用匿名内部类实现接口,无需定义实体类,几行代码就能创建接口实例。
语法结构很直接
Java 中接口不能 new,但可以用匿名内部类方式 instantiating:
- 写法是 new 接口名() { ... },大括号里实现所有抽象方法
- 必须覆盖接口中全部抽象方法,否则编译不通过
- 创建后可赋值给接口类型变量,或直接传参、返回
常见使用场景示例
比如 Runnable、Comparator、OnClickListener 这类函数式接口(哪怕不是 @FunctionalInterface)都适用:
-
启动线程:
new Thread(new Runnable() { public void run() { System.out.println("hello"); } }).start(); -
排序逻辑:
Collections.sort(list, new Comparator<string>() { public int compare(String a, String b) { return b.length() - a.length(); } });</string> -
事件监听:
button.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { toast("clicked"); } });
注意点和替代建议
匿名内部类会隐式持有外部类引用,可能引发内存泄漏(尤其在 Activity/Fragment 中长期持有);另外从 Java 8 起,大多数单方法接口更推荐用 Lambda 表达式:
- Lambda 更简洁:
new Thread(() -> System.out.println("hello")).start(); - 但多方法接口(如 MouseListener)仍需匿名内部类
- 若需复用或逻辑复杂,还是建议单独写实现类,别硬撑匿名
运行时本质没变
编译后,匿名内部类会被生成类似 OuterClass$1.class 的字节码文件,它就是一个实实在在的类——只是你不用手动命名、编译、维护。所以“不写实体类”是编码层面的省事,JVM 层面它仍是标准类实例。











