Java Lambdas和Runnable
我的理解是,Lambda的表达式用于替换抽象实现周围的锅炉板代码。 因此,如果我必须创建一个新线程,它接受一个可运行的接口(函数), 我不必创建新的匿名类,然后提供void run(),然后在其中写入逻辑 相反,您可以简单地使用lambda并将其指向方法,前提是方法签名与run相同,即不接受任何内容,也不返回任何内容 然而,我无法理解下面的实现Java Lambdas和Runnable,java,lambda,Java,Lambda,我的理解是,Lambda的表达式用于替换抽象实现周围的锅炉板代码。 因此,如果我必须创建一个新线程,它接受一个可运行的接口(函数), 我不必创建新的匿名类,然后提供void run(),然后在其中写入逻辑 相反,您可以简单地使用lambda并将其指向方法,前提是方法签名与run相同,即不接受任何内容,也不返回任何内容 然而,我无法理解下面的实现 Thread t= new Thread(()->printStudent(stud)); public static void printSt
Thread t= new Thread(()->printStudent(stud));
public static void printStudent(Student stud) {
System.out.println("Student is "+ stud);
}
在上面的例子中,printStudent接受一个参数(与runnable的run()方法不同),尽管它以某种方式工作
这是如何工作的?您没有将参数传递给
run()
方法,而是()->
部分表示run()
方法。您所做的只是将方法定义为:
@Override
public void run(){
printStudent(stud); //the value of stud from the context copied here
}
以下代码(在类中包装/修改代码):
在功能上等同于:
public class Main {
public static void main(String[] args) {
String item = "Hello, World!"
Thread t = new Thread(new Runnable() {
@Override
public void run() {
printItem(item);
}
});
t.start();
}
public static void printItem(Object item) {
System.out.println(item);
}
}
注意,在第一个示例中,必须使用lambda(->
)。但是,您将无法使用方法引用,因为方法printItem
与Runnable
的签名不匹配。这是非法的:
Thread t = new Thread(Main::printItem);
基本上,方法参考与:
new Runnable() {
@Override
public void run() {
printItem(); // wouldn't compile because the method has parameters
}
}
->
之后的表达式,或->{}
块中的代码,与您在run()
方法中放置的代码相同
Runnable singleExpression = () -> /* this is the code inside run()*/;
Runnable codeBlock = () -> {
// this is the code inside run()
};
stud
变量在封闭范围内定义。该变量的值作为参数传递。因为lamdba不像匿名类,它的this
引用外部类的this
。同样,java streams中的方法引用也是如此。匿名类是如何实现的?我们是说java内部会创建一个匿名类,该类将Student作为实例变量,并通过我们传递的任何内容来丰富它?我不会这么说。它们转换为字节码的方式不同,即运行时行为。简单地说,匿名类被实例化并作为每个引用的类加载,而lambda表达式在所谓的函数接口中被动态调用(这是一条JVM指令)。
Runnable singleExpression = () -> /* this is the code inside run()*/;
Runnable codeBlock = () -> {
// this is the code inside run()
};