匿名内部类是java定义类的方式之一,是没有名字的一种嵌套类
2.为什么要使用匿名内部类?- 在实际开发中,有些接口或者是抽象类的实现方式在程序中只执行一次,但是为了使用它我们却要创建一个实现类或者子类然后重写他的方法,此时便可以使用匿名内部类
- 匿名内部类的本质其实是一个接口的实现类【对象】,或者抽象类的子类【对象】
- 必须要有一个接口、抽象类(普通类也可以,但是方法不会强制重写,不建议使用)
基本格式:
new 接口/类名(参数1, 参数2...){
实现方法1(){
}
实现方法2(){
}
......
};
1. 匿名内部类在使用对象的时候只能使用一次,若要多次使用建议创建实现类
2. 匿名对象,在【调用方法时】,也只能使用唯一一次如果希望同一个对象,调用多次方法,那么就建议给对象起个名字
举个栗子:
假设我们现在有一个接口A,接口里面有个抽象方法v1();
public interface A {
public void v1();
}
那么一般我们要想使用这个v1()方法我们应该怎么办?
- 创建一个实现类AImpl实现接口A
- 重写v1()方法的具体实现
public class AImpl implements A{
@Override
public void v1() {
System.out.println("hello");
}
}
如果这个是实现类AImpl在程序中只使用了一次那么我还单独为这一次使用去创建一个类是不是太浪费了,所以匿名内部类就可以解决我们这个问题。
用匿名内部类我们可以这样写:
new A(){
@Override
public void v1() {
System.out.println("这里重写了v1()");
}
}.v1();
运行结果:
所以,我们并没有创建A的实现类就使用了v1()方法,而且我们还可以对实现类对象进行接收多次使用,这个变量和平常使用多态后的使用方式没有区别。
我们查看一下编译后的字节码文件如下:
至此,我们可以得知,匿名内部类在编译期间,会生成一个名称以$编号结尾的class文件,即它被识别为一个真实的类,仅在编译前(java文件)为匿名的形态。
此外我们还可以在这种情况下使用,如果方法的参数是父类类型,那么调用方法时可以传递子类对象,但是为了图省事不想写子类,那么这个时候可以使用匿名内部类。例如有如下方法:
public static void useCalculator(Calculator calculator){
System.out.println(calculator.calc(10,20));
}
useCalculator参数是一个Calculator父类类型,我们就可以写成这样:
//匿名内部类,可调用方法
useCalculator(new Calculator() {
@Override
public int calc(int a, int b) {
return a+b;
}
});
输出结果30。
通常,我们也习惯用这样的方式创建并启动线程
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("线程启动");
}
}).start();



