代码音符

Lambda表达式与匿名内部类个人理解

创建时间: 2020-1-19 15:43

修改时间: 2023-6-26 18:06

浏览: 92

lambda表达式是Java8的新特性,它的特点是可以让代码更简洁,更易于理解,可以省略掉那些看起来很多余的代码。

我们知道,Java是不能传递方法的,相比于JavaScript可以直接将方法以function类型作为参数在方法间进行传递,Java只能使用对象和基本类型作为参数用来传递。

Java吸取了这个优点,就出现了lambda表达式。但是lambda表达式仍然不能够将方法作为参数进行传递,而是使用类似于内部类的形式,通过传递可执行代码块来达到类似传递方法的目的。

那么我们就进行一次通过策略模式+匿名内部类实现的功能优化成使用lambda表达式的形式的过程吧。

首先,假设我们想要设计一个商城支付的功能:

/**
 * 由于我们会有很多很多的支付方式,所以我们创建一个总接口,要求所有支付方式都要实现此接口
 */
public interface Payment {
    // 要求所有支付方式重写该方法
    void pay();
}

/**
 * 支付的执行类,根据传入的支付方式的对象进行支付操作
 */
public class Finance {
    public void doPay(Payment payment) {
        payment.pay();
        System.out.println("支付完成");
    }
}

main方法测试:

public class Test {
    public static void main(String[] args) {
// 使用内部类来防止支付方式过多导致类的暴增,过一会儿我们就在这里使用lambda改造优化我们的代码
        new Finance().doPay(new Payment() {
            @Override
            public void pay() {
                System.out.println("这里是微信支付");
            }
        });
    }
}

输出结果:

这里是微信支付
支付完成

ambda优化一下

如果是在Java8以前,这已经算是很好的实现方案了,在Java8下,编译器会提示我们main方法里的这段代码可以优化,也就是使用lambda表达式替换掉内部类的部分,main方法那里可以变成这样:

public class Test {
    public static void main(String[] args) {
        // 使用内部类来防止支付方式过多导致类的暴增,过一会儿我们就在这里使用lambda改造优化我们的代码
        new Finance().doPay(() -> System.out.println("这里是微信支付"));
    }
}

省略掉了一些没必要写的代码,代码变的更简洁了。

个人简单分析一下这个lambda:

() -> System.out.println("这里是微信支付")

前面一对括号(),保留了参数列表,在里面定义传入所指向箭头的方法(代码块)的参数,例如:

(num1, num2) -> System.out.println("num1:" + num1 + ",num2:" + num2)

如果代码块中要求有多条语句,还可以这样:

(num1, num2) -> {
    System.out.println("num1:" + num1);
    System.out.println("num2:" + num2);
}

在经过上面的使用lambda表达式优化代码的过程中,我们似乎可以发现一点秘密:

优化前代码:

new Finance().doPay(new Payment() {
    @Override
    public void pay() {
        System.out.println("这里是微信支付");
    }
});

优化后代码:

new Finance().doPay(() -> System.out.println("这里是微信支付"));

我们会发现,被替换的部分其实就是背景颜色加深的那一部分,而那一部分正好是使用lambda表达式替换掉了匿名类的对象。

所以这里的lambda大致等同于这个类。但其本身只是为了执行其箭头后面的代码块(方法),所以:

所以引用一位大佬的总结:

Lambda表达式,其实是一段可传递的代码。Lambda本质是以类的身份,干方法的活。

最后注明一下lambda表达式的适用情况,并非所有接口都可以lambda表达式进行优化,对应lambda表达式的接口必须只具备唯一的抽象方法,例如本文的 Payment 接口。

如果我们在这个接口中添加了任何其他的方法,lambda表达式都将无法使用。

参考文章:

Lambda 表达式有何用处?如何使用? - bravo1988的回答 - 知乎 https://www.zhihu.com/question/20125256/answer/953750947

创建时间: 2020-1-19 15:43

修改时间: 2023-6-26 18:06

浏览: 92

*本文遵循 CC BY-NC-SA 许可协议。转载请注明出处!