java 8选项列表收集列表编译错误

我无法理解之间的区别

Stream<Optional<Integer>> optionalStream = Stream.of(
                Optional.of(1),Optional.empty(),Optional.of(5));

List<Optional<Integer>> optionalList = optionalStream.collect(Collectors.toList());

哪个工作得很好,并且:

List<Optional<Integer>> optionalList1 = Stream.of(
                Optional.of(1),Optional.of(5)).collect(Collectors.toList());

我收到错误的地方

Error:(138,40) java: incompatible types: inference variable T has incompatible bounds
    equality constraints: java.util.Optional<java.lang.Integer>
    lower bounds: java.util.Optional<? extends java.lang.Object>

解决方法

我已经减少了一些示例,并尝试使用-XDverboseResolution = all编译以输出有关类型推断的信息:

final class One {
  void one() {
    Stream<Optional<Integer>> optionalStream = Stream.of(Optional.empty());
    List<Optional<Integer>> optionalList = optionalStream.collect(Collectors.toList());
  }
}

final class Two {
  void two() {
    List<Optional<Integer>> optionalList1 =
        Stream.of(Optional.empty()).collect(Collectors.toList());
  }
}

在Two的情况下,看起来像Stream.of的延迟实例化甚至在查看后续的collect之前完成:

...
Two.java:9: Note: Deferred instantiation of method <T>of(T)
        Stream.of(Optional.empty()).collect(Collectors.toList());
                 ^
  instantiated signature: (Optional<Object>)Stream<Optional<Object>>
  target-type: <none>
  where T is a type-variable:
    T extends Object declared in method <T>of(T)
Two.java:9: Note: resolving method collect in type Stream to candidate 0
        Stream.of(Optional.empty()).collect(Collectors.toList());
...

(“解决方法收集是第一次提到收集)

没有目标类型来约束它;实例化的签名显示它是Stream< Optional< Object>>.

如果你看一个相应的输出

...
One.java:8: Note: Deferred instantiation of method <T>of(T)
    Stream<Optional<Integer>> optionalStream = Stream.of(Optional.empty());
                                                        ^
  instantiated signature: (Optional<Integer>)Stream<Optional<Integer>>
  target-type: Stream<Optional<Integer>>
  where T is a type-variable:
    T extends Object declared in method <T>of(T)
...

它是正确的,因为它知道目标类型.

我不能确切地说为什么延迟实例化在此时为2发生,因为我对应用类型推断的方式不太熟悉.

我认为这是因为Stream.of的调用不被认为是poly表达式,但我无法真正说服自己为什么(请参阅编辑历史记录中的一些不连贯的ramblings).

我建议的修复是将类型提示应用于Optional.empty(),即Optional.< Integer> empty().这具有在推理中更早获取Optional项的实际类型的效果,因此在延迟实例化时已知事件,尽管目标类型仍然是未知的:

final class Three {
  void three() {
    List<Optional<Integer>> optionalList1 =
        Stream.of(Optional.<Integer>empty()).collect(Collectors.toList());
  }
}

...
Three.java:9: Note: resolving method of in type Stream to candidate 1
        Stream.of(Optional.<Integer>empty()).collect(Collectors.toList());
              ^
  phase: BASIC
  with actuals: Optional<Integer>
  with type-args: no arguments
  candidates:
      #0 not applicable method found: <T#1>of(T#1...)
        (cannot infer type-variable(s) T#1
          (argument mismatch; Optional<Integer> cannot be converted to T#1[]))
      #1 applicable method found: <T#2>of(T#2)
        (partially instantiated to: (Optional<Integer>)Stream<Optional<Integer>>)
  where T#1,T#2 are type-variables:
    T#1 extends Object declared in method <T#1>of(T#1...)
    T#2 extends Object declared in method <T#2>of(T#2)
Three.java:9: Note: Deferred instantiation of method <T>of(T)
        Stream.of(Optional.<Integer>empty()).collect(Collectors.toList());
                 ^
  instantiated signature: (Optional<Integer>)Stream<Optional<Integer>>
  target-type: <none>
  where T is a type-variable:
    T extends Object declared in method <T>of(T)
...

相关文章

Java中的String是不可变对象 在面向对象及函数编程语言中,不...
String, StringBuffer 和 StringBuilder 可变性 String不可变...
序列化:把对象转换为字节序列的过程称为对象的序列化. 反序...
先说结论,是对象!可以继续往下看 数组是不是对象 什么是对...
为什么浮点数 float 或 double 运算的时候会有精度丢失的风险...
面试题引入 这里引申出一个经典问题,看下面代码 Integer a ...