[英]Generics: Upper Bounded Wildcards conversion/casting error
这是测试:
@Test
public void genericsTest() {
String s = "x";
List<? extends String> strings = singletonList(s);
Optional<Function<String, List<? extends String>>> optionalSelector = Optional.empty();
optionalSelector.map(selector -> selector.apply(s)).orElse(strings);
}
这是错误:
java: incompatible types: java.util.List<capture#1 of ? extends java.lang.String> cannot be converted to java.util.List<capture#2 of ? extends java.lang.String>
当然,它可以使用原始类型技巧来修复。
optionalSelector.map(selector -> selector.apply(s)).orElse((List)strings);
但我想了解这个错误的原因。
更新 :
它不是带有通配符的列表的重复导致Generic voodoo错误 ,这是关于添加到上限通配符列表; 通配符指南中也很好地描述了这个主题。
在我的情况下,我不会尝试在列表中添加内容,如上所示。
此外,错误消息也不同。
这里的多级类型推断似乎有问题。 有了这条线:
optionalSelector.map(selector -> selector.apply(s)).orElse(strings);
通过调用map
,您正在尝试转换原始的Optional<Function<String, List<? extends String>>>
Optional<Function<String, List<? extends String>>>
为Optional<List<? extends String>>
Optional<List<? extends String>>
。 然后,使用orElse
,您尝试将其转换为List<? extends String>
List<? extends String>
。 这看似合理。
通过给中间步骤一个显式类型,我可以让它编译而不需要转换为原始类型。
Optional<List<? extends String>> intermedSelector = optionalSelector.map(selector -> selector.apply(s));
intermedSelector.orElse(strings);
这表明如果编译器可以推断出map
的调用结果是一个Optional<List<? extends String>>
Optional<List<? extends String>>
,然后调用orElse
将编译。
但是,我可以将显式类型更改为intermedSelector
的声明编译的内容,但是对orElse
的调用不会编译。 我从Optional<List<? extends String>>
更改了interMedSelector
的显式类型Optional<List<? extends String>>
Optional<List<? extends String>>
为Optional<? extends List<? extends String>>
Optional<? extends List<? extends String>>
Optional<? extends List<? extends String>>
,添加? extends
? extends
。
Optional<? extends List<? extends String>> intermedSelector = optionalSelector.map(selector -> selector.apply(s));
intermedSelector.orElse(strings);
这里的错误类似于你得到的错误:
J.java:26: error: incompatible types: List<CAP#1> cannot be converted to CAP#2
List<? extends String> result = intermedSelector.orElse(strings);
^
where CAP#1,CAP#2 are fresh type-variables:
CAP#1 extends String from capture of ? extends String
CAP#2 extends List<? extends String> from capture of ? extends List<? extends String>
使用您的代码,编译器必须推断出一些意外的,但与Optional<List<? extends String>>
Optional<List<? extends String>>
。 我不知道编译器的捕获类型是否是Optional<? extends List<? extends String>>
Optional<? extends List<? extends String>>
Optional<? extends List<? extends String>>
或其他东西,但这似乎是你得到错误的原因。
我的解决方案
Optional<List<? extends String>> intermedSelector = optionalSelector.map(selector -> selector.apply(s));
intermedSelector.orElse(strings);
如果我为map
的调用提供了正确的类型参数,则可以在一个语句中表示,因此编译器不会推断出一些意外的事情。
optionalSelector.<List<? extends String>>map(selector -> selector.apply(s)).orElse(strings);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.