extends也编译--Predicate extends String> predicate = s -> s.startsWith("g")--不过,我们不能将String馈送给这个谓词:)另请参阅我关于通配符的文章。
stackoverflow.com/questions/33085151/…
Predicate super String>并不意味着您可以将Object传递给它(这样做会导致编译器错误)。签名Predicate super String>仅仅意味着它可能是一个Predicate,这是正常的,因为该谓词仍然能够处理String输入。换句话说,Predicate super String>表示这个谓词可以使用字符串,不管它的实际类型如何,所以Predicate是Predicate super String>的有效实现。
If T is a wildcard-parameterized functional interface type and the lambda expression is implicitly typed, then the ground target type is the non-wildcard parameterization (§9.9) of T.
号
强调我的。所以当你写作的时候
1
Predicate<?super String> predicate = s -> s.startsWith("g");
Predicate<String> pred =(Predicate<String>)(s -> s.startsWith("g"));
Predicate<?super String> predicate = pred;
鉴于lambdas类型参数是具体的,在应用了正常类型转换规则之后:Predicate是Predicate super String>或Predicate extends String>。因此,Predicate super String>和Predicate extends String>都应该编译。实际上,这两个版本都适用于Javac8u25、8u45、8u71以及ECJ3.11.1。