我正在学习Lambda表达式,我知道可以在Runnable功能界面和Thread类中使用它们。
我试图创建自己的:
package tests;
public interface Blabla
{
public void doStuff();
}
编译这个简单的测试:
Blabla bla = () -> System.out.println("Lol");
然后我尝试创建一个类似Thread
的类package tests;
public class Dodo implements Blabla
{
public void doStuff()
{
// TODO Auto-generated method stub
}
}
这不会编译:
Dodo dodo = () -> System.out.println("LoL");
我无法解释如何创建一个允许使用lambda表达式的类。
如何在不作为接口的情况下允许使用Lambda表达式?
答案 0 :(得分:5)
如何在不作为接口的情况下允许使用Lambda表达式?
我认为你对Thread类如何使用lambdas感到有些困惑。 lambda不会转换为Thread类本身的实例;相反,lambdas被转换为Runnable功能接口的子类的实例,然后传递给已经overloaded to take a Runnable object的Thread构造函数。
因此,当你做这样的事情时:
new Thread(() -> System.out.println("Lol")).start();
lambda未转换为您正在创建的Thread对象。相反,它被转换为传递给Thread构造函数的Runnable对象。
如果将lambda与Thread对象分开,则更清楚:
Runnable temp = () -> System.out.println("Lol");
new Thread(temp).start();
考虑一个Thread 执行一个函数而不是 一个函数可能会有所帮助。您必须保持Thread执行的功能与Thread本身不同。
请注意,lambdas转换为对象的方式是一个实现细节,在将来的Java版本中可能会发生变化(Java 1.8.0_11是编写本答案时的最新版本)。请参阅下面的Stuart Marks的评论。
我无法解释如何创建一个允许使用lambda表达式的类。
如果我正确理解你,你希望写一个类,这样你就可以根据该类创建一个lambda。
不幸的是,你做不到。请参阅Java语言规范,第15.27节:
评估lambda表达式会产生一个功能接口的实例(§9.8)。
这里的关键点是lambda是接口的一个实例。因此,您不能使用lambda直接对类进行子类化。有关这方面的理由可以在Brian Goetz的this电子邮件中找到JDK lambda-dev邮件列表(感谢Stuart Marks指出这一点!);简而言之,这个决定至少部分地做出了,所以Java可以继续朝着新的方向发展。
你可以做的是编写一个类,其构造函数和/或方法将一个或多个函数接口作为参数,让你通过传递实例来使用lambdas类周围的功能接口(如Thread类)。目前(据我所知),这几乎和它一样好。
答案 1 :(得分:0)
lambda表达式只是编写匿名类的简短形式,通过使用lambda表达式,我们可以在任何我们想要的地方声明方法,而不需要任何名称。
编写匿名类对象的唯一目的是覆盖其方法并提供我们自己的功能,但对于该单个方法,我们总是需要声明该类。使用lambda表达式,我们可以消除匿名类的声明,我们可以简单地提供方法的定义。
例如,我们使用下面的代码来创建一个线程
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("Running thread using anonymous class");
}
};
Thread t = new Thread(runnable);
但是使用lambda表达式我们可以很容易地说
Runnable runnable = () -> System.out.println("Running thread using lambda expression");
Thread t = new Thread(runnable);
或者
Thread t = new Thread(() -> System.out.println("Running thread using lambda expression"));
因此,通过编写Runnable runnable = () -> System.out.println("Running thread using lambda expression");
,我们告诉Java创建一个Runnable
类型的匿名对象,并提供run()
方法的主体。
Lambda表达式仅适用于functional interfaces
(一个只有一个方法的接口),因为我们正在为方法提供实体。因此,如果一个接口有多个方法,并且允许我们在其上创建一个lambda,那么编译器将如何识别这个方法体所属的方法。
Lambda Expression和Anonymous类之间的差异如下
您可以在Java Lambda Expression Explained with Example上阅读更多内容。