Return Java 中的 lambda 值
Return value by lambda in Java
到目前为止,我设法找到了所有我需要的答案,但这个让我很困惑。假设我们有示例代码:
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 Study Guide (Exam 1Z0-808) 书中说这两行是等价的:
a -> a.canHop()
(Animal a) -> { return a.canHop(); }
这是否意味着,在幕后,Java 在代码中添加了关键字 return第一个案例?
如果答案是肯定的,那么接下来的代码如何编译(想象其他一切都在适当的地方):
static int counter = 0;
ExecutorService service = Executors.newSingleThreadExecutor();
service.execute(() -> counter++));
如果我们知道 execute 和 Runnable 的 运行 的签名是:
void execute(Runnable command)
void run()
如果答案是否定的,那么 Java 如何知道什么时候需要 return 什么时候不需要?也许在
a -> a.canHop()
我们想忽略 布尔值 return 类型方法的情况。
您对 return
语句的范围感到困惑。 return
语句(无论是作为字节码由编译器插入还是作为源代码由程序员插入)returns 来自 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");
}
Does this mean that, behind the scenes, Java adds keyword return to code in the first case?
不,编译器生成字节码,它可能会生成相同的字节码,但不会更改语法,然后再次编译。
we wanted to ignore boolean return type of method.
它可以根据正在考虑的功能接口忽略某个值。
a -> a.canHop()
可能是
(Animal a) -> { return a.canHop(); }
或
(Animal a) -> { a.canHop(); }
基于上下文,但如果可能,它倾向于第一个。
考虑 ExecutorService.submit(Callable<T>)
和 ExecutorService.submit(Runnable)
ExecutorService es = Executors.newSingleThreadExecutor();
es.execute(() -> counter++); // has to be Runnable
es.submit(() -> counter++); // Callable<Integer> or Runnable?
保存 return 类型你可以看到它是 Callable<Integer>
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
第一个submit
拿一个Runnable
所以Future.get()
returnsnull
第二个 submit
默认为 Callable
所以 Future.get()
returns 2
第三个 submit
只能是 void
return 值所以它必须是 Runnable
所以 Future.get()
returns null
是的,当只指定一个语句时,它的值自动从 lambda return编辑。
那么,由于Runnable
是一个Functional Interface,所以可以定义为lambda。 return 类型是 void
,因此 lambda 中的任何 return 值都将被忽略。
到目前为止,我设法找到了所有我需要的答案,但这个让我很困惑。假设我们有示例代码:
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 Study Guide (Exam 1Z0-808) 书中说这两行是等价的:
a -> a.canHop()
(Animal a) -> { return a.canHop(); }
这是否意味着,在幕后,Java 在代码中添加了关键字 return第一个案例?
如果答案是肯定的,那么接下来的代码如何编译(想象其他一切都在适当的地方):
static int counter = 0;
ExecutorService service = Executors.newSingleThreadExecutor();
service.execute(() -> counter++));
如果我们知道 execute 和 Runnable 的 运行 的签名是:
void execute(Runnable command)
void run()
如果答案是否定的,那么 Java 如何知道什么时候需要 return 什么时候不需要?也许在
a -> a.canHop()
我们想忽略 布尔值 return 类型方法的情况。
您对 return
语句的范围感到困惑。 return
语句(无论是作为字节码由编译器插入还是作为源代码由程序员插入)returns 来自 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");
}
Does this mean that, behind the scenes, Java adds keyword return to code in the first case?
不,编译器生成字节码,它可能会生成相同的字节码,但不会更改语法,然后再次编译。
we wanted to ignore boolean return type of method.
它可以根据正在考虑的功能接口忽略某个值。
a -> a.canHop()
可能是
(Animal a) -> { return a.canHop(); }
或
(Animal a) -> { a.canHop(); }
基于上下文,但如果可能,它倾向于第一个。
考虑 ExecutorService.submit(Callable<T>)
和 ExecutorService.submit(Runnable)
ExecutorService es = Executors.newSingleThreadExecutor();
es.execute(() -> counter++); // has to be Runnable
es.submit(() -> counter++); // Callable<Integer> or Runnable?
保存 return 类型你可以看到它是 Callable<Integer>
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
第一个submit
拿一个Runnable
所以Future.get()
returnsnull
第二个 submit
默认为 Callable
所以 Future.get()
returns 2
第三个 submit
只能是 void
return 值所以它必须是 Runnable
所以 Future.get()
returns null
是的,当只指定一个语句时,它的值自动从 lambda return编辑。
那么,由于Runnable
是一个Functional Interface,所以可以定义为lambda。 return 类型是 void
,因此 lambda 中的任何 return 值都将被忽略。