Eclipse IDE Java 隐式转换
Eclipse IDE Java implicit casting
在将我的 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
return 是 Stream<Object>
,而不是 Stream<MyInterface>
。在 Oxygen 中,它没有(return 类型是 Stream<MyInterface>
)。看起来有些东西正在隐式地将 filter
的 return 类型转换为 Stream<? extends MyClass, MyInterface>
,然后导致 Stream.concat
returning 预期的类型。当然,这在语义上是安全的,因为 filter
编辑的流 return 中的所有元素都实现了 MyInterface
.
为什么这段代码会被破坏?我怎样才能获得以前的行为?
总结:
- 您的代码无效。
- Oxygen 的 Java 编译器错误地允许您编译代码。
- Photon 的 Java 编译器正确地报告了您的代码错误。
concat()
将 return 一个 Stream,其类型最接近被连接的流的类型。例如,如果你 concat()
a Stream<Int>
with a Stream<Long>
那么 concat()
将 return a Stream<Number>
.
并且如果您 concat()
两个元素之间没有关系的流,例如 Stream<String>
和 Stream<Long>
,那么 concat()
将 return一个Stream<Object>
。这就是您的代码中发生的情况,因为 MyClass
和 MyInterface
彼此没有任何关系,除了 Object
作为 parent.
It looks like something was implicitly casting the return type of
filter to Stream which then lead to
Stream.concat returning the expected type.
这个解释看起来很诱人,因为它似乎符合事实,但如果将过滤器中的谓词更改为测试 Runnable
而不是 MyInterface
,会发生什么情况?
Stream<MyInterface> concatenation2 = Stream.concat(
myClassStream.filter(element -> element instanceof Runnable),
myInterfaceStream);
代码仍在编译,工具提示未更改,因此过滤显然不会影响 return 类型。换句话说,concat()
的第一个参数将 return 一个 Stream<MyClass>
而不管 filter()
中做了什么。您的过滤器保证它也只会 return MyInterface
元素这一事实无关紧要,但它似乎很重要,因为从 concat()
接收 Stream 的变量类型是 Stream<MyInterface>
.
如果从 concat()
接收 Stream 的变量类型从 MyInterface
更改为荒谬且无意义的东西,例如 Deque<LocalDateTime>
,会发生什么?...
Stream<Deque<LocalDateTime>> concatenation3 = Stream.concat(
myClassStream.filter(element -> element instanceof MyInterface),
myInterfaceStream);
有两点值得注意:
- 即使该代码显然无效,它仍然可以在 Oxygen 上编译(但不能在 Photon 上编译)。
concat()
的工具提示现在显示其 return 类型为 Stream<Deque<LocalDateTime>>
,这显然没有意义。
Why did this code break? How could I get previous behavior?
Oxygen 的编译器允许使用 Stream.concat()
进行无效的变量定义,这似乎已在 Photon 中修复。你不应该想要以前的行为,因为它是不正确的。
在将我的 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
return 是 Stream<Object>
,而不是 Stream<MyInterface>
。在 Oxygen 中,它没有(return 类型是 Stream<MyInterface>
)。看起来有些东西正在隐式地将 filter
的 return 类型转换为 Stream<? extends MyClass, MyInterface>
,然后导致 Stream.concat
returning 预期的类型。当然,这在语义上是安全的,因为 filter
编辑的流 return 中的所有元素都实现了 MyInterface
.
为什么这段代码会被破坏?我怎样才能获得以前的行为?
总结:
- 您的代码无效。
- Oxygen 的 Java 编译器错误地允许您编译代码。
- Photon 的 Java 编译器正确地报告了您的代码错误。
concat()
将 return 一个 Stream,其类型最接近被连接的流的类型。例如,如果你 concat()
a Stream<Int>
with a Stream<Long>
那么 concat()
将 return a Stream<Number>
.
并且如果您 concat()
两个元素之间没有关系的流,例如 Stream<String>
和 Stream<Long>
,那么 concat()
将 return一个Stream<Object>
。这就是您的代码中发生的情况,因为 MyClass
和 MyInterface
彼此没有任何关系,除了 Object
作为 parent.
It looks like something was implicitly casting the return type of filter to Stream which then lead to Stream.concat returning the expected type.
这个解释看起来很诱人,因为它似乎符合事实,但如果将过滤器中的谓词更改为测试 Runnable
而不是 MyInterface
,会发生什么情况?
Stream<MyInterface> concatenation2 = Stream.concat(
myClassStream.filter(element -> element instanceof Runnable),
myInterfaceStream);
代码仍在编译,工具提示未更改,因此过滤显然不会影响 return 类型。换句话说,concat()
的第一个参数将 return 一个 Stream<MyClass>
而不管 filter()
中做了什么。您的过滤器保证它也只会 return MyInterface
元素这一事实无关紧要,但它似乎很重要,因为从 concat()
接收 Stream 的变量类型是 Stream<MyInterface>
.
如果从 concat()
接收 Stream 的变量类型从 MyInterface
更改为荒谬且无意义的东西,例如 Deque<LocalDateTime>
,会发生什么?...
Stream<Deque<LocalDateTime>> concatenation3 = Stream.concat(
myClassStream.filter(element -> element instanceof MyInterface),
myInterfaceStream);
有两点值得注意:
- 即使该代码显然无效,它仍然可以在 Oxygen 上编译(但不能在 Photon 上编译)。
concat()
的工具提示现在显示其 return 类型为Stream<Deque<LocalDateTime>>
,这显然没有意义。
Why did this code break? How could I get previous behavior?
Oxygen 的编译器允许使用 Stream.concat()
进行无效的变量定义,这似乎已在 Photon 中修复。你不应该想要以前的行为,因为它是不正确的。