【发布时间】:2016-05-20 07:07:22
【问题描述】:
在学习 Java8 Streams 时,我遇到了以下代码 sn-p:
Predicate<? super String> predicate = s -> s.startsWith("g");
由于通用参数是一个下限,我认为这不会编译。在我看来,如果 Object 是 String 的超类型,那么传入 Object 类型应该会破坏它,因为 Object 没有 startsWith() 函数。但是,我很惊讶地看到它没有任何问题。
此外,当我调整谓词以获取上限时:
<? extends String>,
它不会编译。
我以为我理解了上限和下限的含义,但显然,我遗漏了一些东西。谁能帮助解释为什么下限适用于此 lambda?
【问题讨论】:
-
extends也可以编译 --Predicate<? extends String> predicate = s -> s.startsWith("g")-- 但是,我们不能将String提供给这个谓词:) 另请参阅我的 article on wildcard -
Predicate<? super String>确实 not 暗示您可以将Object传递给它(这样做会产生编译器错误)。签名Predicate<? super String>只是暗示它可能是Predicate<Object>,这没关系,因为该谓词仍然能够处理String输入。换句话说,Predicate<? super String>表示此谓词可以使用字符串,而不管其实际类型如何,因此Predicate<String>是Predicate<? super String>的有效实现。 -
我很抱歉没有提供完整的代码。没有编译的实际代码是之后出现的 boolean test = anyMatch(predicate); 行。实际的谓词行本身确实以上限和下限语法编译。顺理成章地思考了一会儿,我明白了为什么 anyMatch 会有这样的签名。
标签: java generics lambda java-8 predicate