java 8选项列表收集列表编译错误
我无法理解之间的区别
Stream<Optional> optionalStream = Stream.of( Optional.of(1), Optional.empty(), Optional.of(5)); List<Optional> optionalList = optionalStream.collect(Collectors.toList());
哪个工作得很好,并且:
List<Optional> optionalList1 = Stream.of( Optional.of(1), Optional.empty(), Optional.of(5)).collect(Collectors.toList());
我收到错误的地方
Error:(138, 40) java: incompatible types: inference variable T has incompatible bounds equality constraints: java.util.Optional lower bounds: java.util.Optional
我已经减少了一些示例,并尝试使用-XDverboseResolution=all
编译以输出有关类型推断的信息:
final class One { void one() { Stream> optionalStream = Stream.of(Optional.empty()); List> optionalList = optionalStream.collect(Collectors.toList()); } } final class Two { void two() { List> optionalList1 = Stream.of(Optional.empty()).collect(Collectors.toList()); } }
在Two
的情况下,看起来Stream.of
的延迟实例化甚至在查看后续的collect
之前完成:
... Two.java:9: Note: Deferred instantiation of method of(T) Stream.of(Optional.empty()).collect(Collectors.toList()); ^ instantiated signature: (Optional
(“解决方法collect
是第一次提到collect
)
没有target-type
来约束它; 实例化的签名显示它是Stream
。
如果你看一个相应的输出:
... One.java:8: Note: Deferred instantiation of method of(T) Stream> optionalStream = Stream.of(Optional.empty()); ^ instantiated signature: (Optional)Stream> target-type: Stream> where T is a type-variable: T extends Object declared in method of(T) ...
这是正确的,因为它知道目标类型。
我不能确切地说为什么延迟实例化在此时为Two
,因为我对应用类型推断的方式不够熟悉。
我认为这是因为Stream.of
的调用不被认为是一个多义表达式,但我无法真正说服自己为什么(请参阅编辑历史记录中的一些不连贯的ramblings)。
我建议的修复是将类型提示应用于Optional.empty()
,即Optional.
。 这具有在推理中较早获取Optional
的实际类型的效果,因此在延迟实例化时已知事件,尽管目标类型仍然是未知的:
final class Three { void three() { List> optionalList1 = Stream.of(Optional.empty()).collect(Collectors.toList()); } } ... Three.java:9: Note: resolving method of in type Stream to candidate 1 Stream.of(Optional. empty()).collect(Collectors.toList()); ^ phase: BASIC with actuals: Optional with type-args: no arguments candidates: #0 not applicable method found: of(T#1...) (cannot infer type-variable(s) T#1 (argument mismatch; Optional cannot be converted to T#1[])) #1 applicable method found: of(T#2) (partially instantiated to: (Optional )Stream>) where T#1,T#2 are type-variables: T#1 extends Object declared in method of(T#1...) T#2 extends Object declared in method of(T#2) Three.java:9: Note: Deferred instantiation of method of(T) Stream.of(Optional.empty()).collect(Collectors.toList()); ^ instantiated signature: (Optional )Stream> target-type: where T is a type-variable: T extends Object declared in method of(T) ...
Stream.of(...)
或Optional.empty()
是通用方法。 如果您不提供type参数,则会推断出它。 对于Optional.empty()
您将获得Optional
因此Stream.of(Optional.of(1), Optional.empty(), Optional.of(5))
将导致Stream
Stream
。
您可以通过在Stream.
Optional.
或Stream.
提供type参数来解决此问题。 我更喜欢第一个。
- 如何在另一个中嵌入一个DropWizard(带有freemarker)视图?
- 无法通过JBoss远程访问数据源
- 从运行Java Jersey Rest API的HTTP服务器传输大文件
- Spring集成多个UDP入站/出站通道
- JPA:外键注释
- Lombok @builder在一个扩展另一个类的类上
- “hadoop namenode -format”返回java.net.UnknownHostException
- Java:如何防止EntityResolver中的’systemId’#resolveEntity(String publicId,String systemId)从绝对化到当前工作目录
- 使用nio的java中的非阻塞客户端服务器聊天应用程序