java - 为什么要对 lambda 输入参数执行强制转换?
问题描述
我接受,由于下界通配符,这个谓词不应该接受String
没有显式转换的超类。[ 1 , 2 ] 这个问题是关于 lambda 参数列表中的类型安全强制。鉴于第二个块编译失败,为什么允许第一个块在没有警告的情况下编译?似乎在第一种情况下,尽管 lambda 的参数声明,CharSequence
被强制转换String
以满足谓词的边界约束。
Predicate<? super String> predicate1 = (CharSequence c)
-> c.toString().length() > 2 ;
System.out.println(predicate1.test("foo")); // compiles
Predicate<? super String> predicate2 = (CharSequence c)
-> c.toString().length() > 2 ;
System.out.println(predicate2.test((CharSequence)"foo")); // capture error
error: method test in interface Predicate<T> cannot be applied to given types;
out.println(predicate2.test((CharSequence)"foo"));
^
required: CAP#1
found: CharSequence
reason: argument mismatch; CharSequence cannot be converted to CAP#1
where T is a type-variable:
T extends Object declared in interface Predicate
where CAP#1 is a fresh type-variable:
CAP#1 extends Object super: String from capture of ? super String
感谢您在这方面所做的工作。问题似乎是假设 lambda 和通用进程将被迫使用CharSequence
. 但是,现在很明显String
可以在没有编译器错误的情况下提交给 lambda,所以在第一种情况下发生了什么,并且 aString
正在提交给两个进程。泛型过程忽略 lambda 的内容也就不足为奇了。
解决方案
Predicate<? super String> predicate2 = (CharSequence c)
-> c.toString().length() > 2 ;
System.out.println(predicate2.test((CharSequence)"foo")); // capture error
问题是predicate2
说它会接受String
; 你试图通过它一个CharSequence
.
如果将变量的声明更改为
Predicate<? super CharSequence> predicate2
然后它工作。
这不起作用的原因是您可能将 a 传递MyCharSequence implements CharSequence
给谓词:
System.out.println(predicate2.test((CharSequence)new MyCharSequence()));
这不应该被接受,因为predicate2
变量的类型表明它应该只期望得到一个String
. 编译器仅将实际参数的类型视为CharSequence
,因此无法区分“this is a String
”(可以)和“this is a MyCharSequence
”(不可以)。
推荐阅读
- python - 如何使用烧瓶返回多个图像
- websphere - 打开 WAS8.5.5 控制台并单击其中的任何值时出错
- typescript - Firebase Cloud Functions - 实时数据库 - 获取父节点密钥
- javascript - 使用 Aucomplete material-ui 的建议
- google-sheets - 如何在 google-sheets 中旋转 3-d 表格
- bash - Go migrate 不会安装在 MacOS 上
- javascript - 文档谷歌查看器不适用于 iframe
- ios - 如何防止弹出窗口中的阴影 iOS 13
- mysql - SQL 限制每个指定列值的返回行数,在单个查询中
- powershell - Get time in a fixed timezone in PowerShell Cross-Platform