java 中的匿名内部类通过 new 关键字在创建对象的同时定义其实现,适用于需要一次性使用的接口或抽象类。具体做法是在调用处直接编写类体并实例化,编译器会自动生成对应的字节码文件。这种方式省去了单独定义命名类的步骤,使代码更加紧凑,特别适合事件监听器、线程任务等场景。

如何为单方法接口创建匿名内部类
当目标类型是只有一个抽象方法的接口时,可以直接在 new 表达式中重写该方法。这种写法常用于简化回调逻辑,避免为单一方法创建独立的类文件。编译器会推断出实现的接口类型,开发者只需关注方法体的具体逻辑。

public class Main {
public static void main(String[] args) {
// 定义一个单方法接口
interface Greeting {
void sayHello();
}
// 使用匿名内部类实现接口
Greeting greeting = new Greeting() {
@Override
public void sayHello() {
System.out.println("Hello from Anonymous Class");
}
};
// 调用方法
greeting.sayHello();
}
}运行上述代码将输出:Hello from Anonymous Class。这里 Greeting 接口被匿名实现,实例化后直接赋值给变量 greeting。该匿名类没有名字,但具有完整的类结构,包括方法重写和访问修饰符。
立即学习“Java免费学习笔记(深入)”;
如何在多线程中使用匿名内部类
在 Java 中启动线程时,可以通过匿名内部类继承 Thread 类或实现 Runnable 接口来定义线程执行逻辑。这种方式允许在 start() 调用前即时定义行为,无需预先创建子类。对于简单的异步任务,这种内联定义能显著减少样板代码。

public class ThreadExample {
public static void main(String[] args) {
// 方式一:继承 Thread 类
Thread thread1 = new Thread() {
@Override
public void run() {
System.out.println("Thread 1 running: " + Thread.currentThread().getName());
}
};
thread1.start();
// 方式二:实现 Runnable 接口
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Thread 2 running: " + Thread.currentThread().getName());
}
});
thread2.start();
}
}程序运行后会启动两个线程,分别打印各自的名称。匿名内部类在这里实现了 run() 方法,并将其传递给 Thread 构造函数或直接作为新线程的主体。注意,如果继承 Thread,则必须调用 start() 而非直接调用 run(),否则不会在新线程中执行。
匿名内部类访问局部变量有什么限制
匿名内部类在访问外部方法的局部变量时,要求这些变量必须是 effectively final(事实上的最终变量)。这意味着变量在初始化后不能被修改,否则编译器会报错。这一限制源于 JVM 对局部变量的存储机制,匿名内部类实际上是通过拷贝值的方式访问这些变量,而非引用原始变量。若需修改外部状态,应使用数组包装或成员变量。


















