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
so
Future.get()
返回
null

第二个
submit
默认为可调用
so
Future.get()
返回
2


第三个
submit
只能是
void
返回值,因此它必须是
Runnable
so
Future.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