目录
1.直接把这个整体看成一个已经创建好的对象通过 .方法 来调用 如图:
2. 多态:创建参数类型为接口的方法并且利用Lambda简化代码
什么是匿名内部类?
隐藏类名的内部类
格式如下:
(其中创建时包含了 继承 方法重写 创建对象 )
创建匿名内部类:
new 类名或者接口名()
{
重写方法;
}
举例说明:
①继承抽象类的匿名内部类
首先创建一个抽象类Animal
我们想在main方法中创建匿名内部类重写show()方法
简单分析下匿名内部类的整体结构:
首先,大括号包围的内部是一个匿名内部类,相当于Animal的一个子类
其次,new Animal() 这个实际上就是利用Animal的无参构造方法创建了这样一个匿名内部类
最后,这个整体,就是一个匿名内部类对象
创建完成之后,我们有两种方法调用这个对象中的方法
1.直接把这个整体看成一个已经创建好的对象通过 .方法 来调用 如图:
输出为:
2.利用多态性质
一.创建一个方法形参为“父类”的Animal类,然后在方法里对这个匿名内部类执行想要的操作,和其余操作
因为采用了多态,所以沿用了多态的使用方法:
编译看左边,运行看右边(具体可以参照我的另一篇文章:多态的个人理解)
这里我是调用了方法show()
结果为:
二.或者还是利用多态性质,干脆直接创建一个Animal类型的对象(不过是"子类"匿名构造类的构造方法创建的),再用这个对象去调用(当然方法也必须满足多态性质)
结果为:
②实现接口的匿名内部类(含Lambda的使用):
首先创建一个接口SwimDao
创建接口SwimDao的接口实现的匿名内部类,其实和上面抽象类的差不多 ,结构也类似
1.一样当成一个创建好的对象来直接调用里面重写的方法
结果为:
2. 多态:创建参数类型为接口的方法并且利用Lambda简化代码
(与前面抽象类类似,因为类和接口是实现关系,这里也是一种多态,接口和实现类的多态)
不用Lambda简化:
Lambda:jdk8之后java才引入这样的简化方式
但是有一个前提:接口必须是一个函数接口(只有一个抽象方法的接口)
直接用:
(形参)->{重写的方法}
注意事项:
*这里的形参必须和重写方法的形参个数,类型一致(参数类型可以不写)
如图(这时候重写的方法,有了两个形参):
*除此之外,有个特例:当参数只有一个的时候可以不写括号:
从内存角度看匿名内部类
实际上,匿名内部类在字节码文件中拥有自己的名字:所在类+$+序号
这是整个包内的字节码文件,我们可以看到 红框里的就是匿名内部类,而这些匿名内部类是在Test类里面的,所以是Test$序号
接下来我们反编译字节码文件,看看反编译的代码和编译器中的代码有什么不同
输入javap 和对应的字节码 就可以实现反编译
可以看到红框
第一行:
和我们正常创建一个实现接口类格式是一模一样的
final class 类名 implements 接口名
这里简单来看就是:
final class Test$1 implements SwimDao
第二行:
是匿名构造类的构造方法
第三行:
就是我们重写的方法
对比编译器中的代码:
可以明显发现:匿名内部类隐藏了自己的类名,和构造方法名
应用场景:
当我们要创建一个方法,方法的形参是类或者接口的时候
我们一般会传递(类或者接口实现类)的对象,但是这个实现类仅仅用了一次就不用了,
这时候就可以创建匿名内部类来作为参数,简化代码