[英]How does java know the type of a lambda parameter?
在这样的示例代码中,我的 IDE 将我的代码从使用匿名类更改为返回 lambda。 这很酷,但它是如何工作的?
public static Specification<User> getUsersByFirstNameSpec(String name) {
return new Specification<User>() {
@Override
public Predicate toPredicate(Root<User> root,
CriteriaQuery<?> query,
CriteriaBuilder criteriaBuilder) {
Predicate equalPredicate = criteriaBuilder.like(
criteriaBuilder.upper(root.get("firstName")),
name.toUpperCase());
return equalPredicate;
}
};
}
java如何知道3个参数的类型?
public static Specification<User> getUsersByLastNameSpec(String name) {
return (Specification<User>) (root, query, criteriaBuilder) -> {
Predicate equalPredicate = criteriaBuilder.like(
criteriaBuilder.upper(root.get("lastName")),
name.toUpperCase());
return equalPredicate;
};
}
在 java 中,lambdas 被解释为所谓的“功能接口”。
函数式接口是任何接口(如public interface SomeInterface { ... }
),它恰好包含 1 个“非对象、非默认”方法。 因此,对于接口中声明的每个方法,如果它只是在重复java.lang.Object
本身的规范中已经存在的内容(例如, interface Example { String toString(); }
,则忽略它),或者有一个默认的 impl,比如interface Example { default String foo() { return ""; } }
interface Example { default String foo() { return ""; } }
。 那么,还剩下多少方法呢? 如果答案正好是 1(不是 0,不是 2),那么它就是一个函数式接口。
如果您使用 lambda(箭头符号,或typeOrReferenceExpr::someMethod
语法),那么您使用它的地方必须是编译器可以准确找出所要使用的功能接口的地方。 如果不能,则是编译器错误。 例如:
Object o = () -> System.out.println("Hello!");
这是一个编译时错误。 但是这个:
Runnable r = () -> System.out.println("Hello!");
很好; java.lang.Runnable
是一个函数式接口,因为它只有一个相关的方法,即void run();
.
一旦功能接口清晰,lambda 就会被解释为该方法的实现。 因此,在您的示例中,java 知道root
、 query
和criteriaBuilder
的类型,因为编译器可以确定这是接口Specification<User>
一个实现,并且该接口只有一个(非对象,非默认) 方法,其规格为:
Predicate toPredicate(Root<User>, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder)
这就是java知道的。 它还从中计算出任何throws
子句,以及返回类型。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.