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上的教程仓库中找到。