1. 概述

在这个教程中,我们将学习如何在Java中将匿名类转换为lambda表达式

首先,我们会简要介绍什么是匿名类。然后,我们将通过实际例子演示如何回答我们的核心问题。

2. Java中的匿名类

简而言之,如其名称所示,匿名类是一种没有名字的内部类。由于它没有名字,我们需要在一个表达式中同时声明和实例化它

按设计,匿名类继承一个类或实现一个接口。

例如,我们可以使用Runnable作为匿名类,在Java中创建一个新的线程。语法类似于构造函数的调用,只是我们需要将类定义放在一个代码块中:

Thread thread = new Thread(new Runnable() {
    @Override
    public void run() {
        ...
    }
});

现在我们了解了匿名类是什么,让我们看看如何使用lambda表达式重写它。

3. 将匿名类转换为lambda表达式

Lambda表达式提供了一种方便的快捷方式,可以更简洁直接地定义匿名类。

但这只适用于匿名类只有一个方法的情况。现在,让我们逐步了解如何将匿名类转换为lambda表达式。

3.1. 定义匿名类

例如,考虑Sender接口:

public interface Sender {
    String send(String message);
}

如上所述,接口只有一个已声明的方法。这种类型的接口称为函数式接口

接下来,我们创建SenderService接口:

public interface SenderService {
    String callSender(Sender sender);
}

因为callSender()方法接受一个Sender对象作为参数,我们可以将其传递给匿名类。

现在,我们将创建SenderService接口的两个实现。

首先,创建EmailSenderService类:

public class EmailSenderService implements SenderService {

    @Override
    public String callSender(Sender sender) {
        return sender.send("Email Notification");
    }
}

接着,创建SmsSenderService类:

public class SmsSenderService implements SenderService {

    @Override
    public String callSender(Sender sender) {
        return sender.send("SMS Notification");
    }
}

现在,我们将所有部分组合在一起,创建一个测试案例,其中我们将Sender对象作为匿名类传递:

@Test
public void whenPassingAnonymousClass_thenSuccess() {
    SenderService emailSenderService = new EmailSenderService();

    String emailNotif = emailSenderService.callSender(new Sender() {
        @Override
        public String send(String message) {
            return message;
        }
    });

    assertEquals(emailNotif, "Email Notification");
}

如上所示,我们作为匿名类传递了Sender对象,并重写了send()方法。

3.2. 转换匿名类

现在,让我们尝试使用更简洁的方式,使用lambda表达式重写之前的测试案例。

由于send()是唯一定义的方法,编译器知道应该调用哪个方法,因此不需要显式重写它

要将匿名类转换为lambda表达式,我们需要省略new关键字和方法名

@Test
public void whenPassingLambdaExpression_thenSuccess() {
    SenderService smsSenderService = new SmsSenderService();

    String smsNotif = smsSenderService.callSender((String message) -> {
        return message;
    });

    assertEquals(smsNotif, "SMS Notification");
}

如上所述,我们用箭头将send()参数和其体替换掉了匿名类。

我们还可以进一步简化:通过移除参数类型和return语句,我们可以将lambda语句改为lambda表达式

String smsNotif = smsSenderService.callSender(message -> message);

如您所见,我们不需要指定参数类型,因为编译器可以隐式推断它。

4. 总结

在这篇文章中,我们学习了如何在Java中用lambda表达式替换匿名类。

我们沿途解释了匿名类是什么,以及如何将其转换为lambda表达式。

如往常一样,本文中使用的代码可以在GitHub上的教程仓库中找到。