匿名内部类与Lambda表达式
一.匿名内部类
谁没有名字:匿名内部类指的是接口的实现类 或者 抽象类的子类没有名字。
1.前提:
1)必须要有一个接口、抽象类(普通类也可以,但是方法不会强制重写,不建议)
2)格式:
new 接口/抽象类(){
//复写抽象方法
}
3)本质:匿名内部类的本质其实是一个接口的实现类【对象】,或者抽象类的子类【对象】
2.使用场景:
在实际运用中,如果方法的参数是父类类型,那么调用方法时可以传递子类对象,但是为了图省事不想写子类,那么这个时候可以使用匿名内部类。
public class Demo4 {
public static void main(String[] args) {
//匿名内部类,可调用方法
useCalculator(new Calculator() {
@Override
public int calc(int a, int b) {
return a+b;
}
});
}
public static void useCalculator(Calculator calculator){
System.out.println(calculator.calc(10,20));
}
}
interface Calculator{
int calc(int a,int b);
}
打印结果
------------------------------------------------------------------
30
二.Lambda表达式
1.前提:
Lambda表达式的使用是由条件的,必须要有一个【函数式接口】,在接口中只能有一个抽象方法【但是可以有默认方法和静态方法】。
public class Demo4 {
public static void main(String[] args) {
//Lambda表达式(简化匿名内部类)
useCalculator((a, b) -> a+b);
}
public static void useCalculator(Calculator calculator){
System.out.println(calculator.calc(10,20));
}
}
@FunctionalInterface//注解:可用于检查是否为函数式接口
interface Calculator{
int calc(int a,int b);
//可以有默认方法,通过接口实现类对象调用
default void getSum(int x,int y){
System.out.println(x+y);
}
//通过类名调用
static void getMin(int m,int n){
System.out.println(Math.min(m,n));
}
}
打印结果
------------------------------------------------------------------
30
//1. Lambda标准格式
(参数类型1 参数名1,参数类型2 参数名2) -> { 方法体; return 返回值; }
//2. Lambda省略格式,省略参数数据类型
(参数名1,参数名2) -> { 方法体; return 返回值; }
//3. Lambda省略格式,{}中的代码只有一条语句,那么大括号可以省略、rerturn和分号都要省略
(参数名1,参数名2) -> 返回值
//4. Lambda省略格式,参数只有一个时,()可以省略
参数名 -> 返回值
三.两者的不同之处
1.所需类型不同
匿名内部类:可以是接口,也可以是抽象类,还可以是具体类
Lambda表达式:只能是接口
2.使用限制不同
如果接口中有且仅有一个抽象方法,可以使用Lambda表达式,也可以使用匿名内部类如果接口中多于一个抽象方法,只能使用匿名内部类,而不能使用Lambda表达式
3.实现原理不同
匿名内部类∶编译之后,产生一个单独的.class字节码文件
Lambda表达式︰编译之后,没有一个单独的.class字节码文件。对应的字节码会在运行的时候动态生成