Java中lambda的返回值
到目前为止,我设法找到了所有我需要的答案,但这一个让我困惑。假设我们有示例代码:Java中lambda的返回值,java,lambda,runnable,Java,Lambda,Runnable,到目前为止,我设法找到了所有我需要的答案,但这一个让我困惑。假设我们有示例代码: public class Animal { private String species; private boolean canHop; private boolean canSwim; public Animal(String speciesName, boolean hopper, boolean swimmer) { species = speciesName;
public class Animal {
private String species;
private boolean canHop;
private boolean canSwim;
public Animal(String speciesName, boolean hopper, boolean swimmer) {
species = speciesName;
canHop = hopper;
canSwim = swimmer;
}
public boolean canHop() { return canHop; }
public boolean canSwim() { return canSwim; }
public String toString() { return species; }
}
public interface CheckAnimal {
public boolean test(Animal a);
}
public class FindSameAnimals {
private static void print(Animal animal, CheckAnimal trait) {
if(trait.test(animal)){
System.out.println(animal);
}
public static void main(String[] args) {
print(new Animal("fish", false, true), a -> a.canHop());
}
}
OCA研究指南(考试1Z0-808)一书中说,这两条线是等效的:
a -> a.canHop()
(Animal a) -> { return a.canHop(); }
这是否意味着,在第一种情况下,Java会在代码中添加关键字return
如果答案是肯定的,那么下一个代码是如何编译的(假设其他所有代码都在适当的位置):
如果我们知道execute和Runnable运行的签名是:
如果答案是否定的,那么Java如何知道何时需要返回某些内容,何时不需要返回?也许在
a -> a.canHop()
我们希望忽略方法的布尔返回类型。您对
return
语句的范围感到困惑。return
语句(无论是作为字节码由编译器插入还是作为源代码由程序员插入)从lambda返回,而不是从调用lambda的方法返回
void foo() {
Supplier<String> s = () -> { return "bar" };
String s = s.get(); // s is assigned to "bar"
// Execution continues as the return statement in the lambda only returns from the lambda and not the enclosing method
System.out.println("This will print");
}
void foo(){
供应商s=()->{return“bar”};
字符串s=s.get();//s被分配给“bar”
//执行将继续,因为lambda中的return语句仅从lambda而不是封闭方法返回
System.out.println(“这将打印”);
}
这是否意味着,在第一种情况下,Java会在代码中添加关键字return
不,编译器生成字节码,它可能会生成相同的字节码,但不会更改语法,然后再次编译
我们希望忽略方法的布尔返回类型
它可以根据所考虑的功能接口忽略一个值
a -> a.canHop()
可能是
(Animal a) -> { return a.canHop(); }
或
根据上下文,如果可能,它倾向于第一种
考虑ExecutorService.submit(可调用)
和ExecutorService.submit(可运行)
第一个submit
获取Runnable
soFuture.get()
返回null
第二个submit
默认为可调用soFuture.get()
返回2
第三个submit
只能是void
返回值,因此它必须是Runnable
soFuture.get()
返回null是,当只指定一条语句时,它的值会从lambda自动返回
void foo() {
Supplier<String> s = () -> { return "bar" };
String s = s.get(); // s is assigned to "bar"
// Execution continues as the return statement in the lambda only returns from the lambda and not the enclosing method
System.out.println("This will print");
}
然后,因为是一个功能接口,所以可以将其定义为lambda。返回类型为void
,因此lambda中的任何返回值都将被忽略。它知道在可运行的情况下可以忽略返回类型,因为run()返回void。它知道它不能忽略CheckAnimal案例中的返回类型,因为test()不会返回void。lambada执行方法应该执行的操作,如果方法包含返回类型,则lambda将提供其他操作,这是编写方法的快捷方式,所以不要混淆自己,以防执行只需要运行:es.execute(()->counter++);那么,FREMAN任何不返回值的方法都只能产生副作用。
(Animal a) -> { return a.canHop(); }
(Animal a) -> { a.canHop(); }
ExecutorService es = Executors.newSingleThreadExecutor();
es.execute(() -> counter++); // has to be Runnable
es.submit(() -> counter++); // Callable<Integer> or Runnable?
final Future<Integer> submit = es.submit(() -> counter++);
static int counter = 0;
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService es = Executors.newSingleThreadExecutor();
// execute only takes Runnable
es.execute(() -> counter++);
// force the lambda to be Runnable
final Future<?> submit = es.submit((Runnable) () -> counter++);
System.out.println(submit.get());
// returns a value so it's a Callable<Integer>
final Future<Integer> submit2 = es.submit(() -> counter++);
System.out.println(submit2.get());
// returns nothing so it must be Runnable
final Future<?> submit3 = es.submit(() -> System.out.println("counter: " + counter));
System.out.println(submit3.get());
es.shutdown();
}
null
2
counter: 3
null