【发布时间】:2018-07-18 10:18:16
【问题描述】:
在将我的 Eclipse IDE 安装从 Oxygen.3a (4.7.3) 更新到 Photon 时,我注意到尽管之前编译(和工作)正常,但我的一些代码已经损坏。
考虑以下代码:
import java.util.ArrayList;
import java.util.stream.Stream;
public class Test {
class MyClass {
}
interface MyInterface {
}
public static void main(String[] args) {
Stream<MyClass> myClassStream = new ArrayList<MyClass>().stream();
Stream<MyInterface> myInterfaceStream = new ArrayList<MyInterface>().stream();
Stream<MyInterface> concatenation = Stream.concat(
// Tooltip for filter() displays the result type of Stream<MyClass>
myClassStream.filter(element -> element instanceof MyInterface),
// Tooltip displays type Stream<MyInterface>
myInterfaceStream);
}
}
在 Photon 中,会出现一个错误,指出 Stream.concat 返回 Stream<Object>,而不是 Stream<MyInterface>。在 Oxygen 中,它没有(返回类型为 Stream<MyInterface>)。看起来有些东西隐式地将filter 的返回类型转换为Stream<? extends MyClass, MyInterface>,然后导致Stream.concat 返回预期的类型。当然,这在语义上是安全的,因为filter 返回的流中的所有元素都实现了MyInterface。
为什么这段代码会中断?我怎样才能得到以前的行为?
【问题讨论】:
-
错误报告似乎有所改进。做
myClassStream.filter(...).(MyInterface.class::cast) -
Eclipse 使用自己的 Java 编译器,所以这与 javac 无关。
-
好吧,在实际代码中
MyClass和MyInterface也没有连接。但是,MyClass的几个子类实现了MyInterface,过滤器会尝试对它们进行排序。 -
@JoopEggen 喜欢这样吗?
myClassStream.filter(element -> element instanceof MyInterface).map(MyInterface.class::cast) -
是的。现在流属于 MyInterface,而不是 MyClass,它在运行时恰好是 MyInterface 对象。
标签: java eclipse casting implicit-conversion