首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Eclipse隐式转换

Eclipse隐式转换
EN

Stack Overflow用户
提问于 2018-07-18 10:18:16
回答 1查看 257关注 0票数 3

在将Eclipse安装从Oxygen.3a (4.7.3)更新到Photon时,我注意到,尽管以前编译(和工作)还不错,但我的一些代码还是坏了。

考虑以下代码:

代码语言:javascript
复制
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);
    }

}

在光子中,出现一个错误,说明Stream.concat返回的是Stream<Object>,而不是Stream<MyInterface>。在氧气中,没有(返回类型为Stream<MyInterface>)。它看起来像是在隐式地将filter的返回类型转换为Stream<? extends MyClass, MyInterface>,这会导致Stream.concat返回预期的类型。当然,这在语义上是安全的,因为filter返回的流中的所有元素都实现了MyInterface

为什么这段代码会中断?我怎么会有以前的行为?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-07-20 18:52:28

摘要:

  • 你的代码无效。
  • 氧气的Java编译器不正确地允许您的代码编译。
  • 光子的Java编译器正确地报告了代码中的错误。

concat()将返回一个类型的流,该流与所连接的流的类型最接近。例如,如果您使用concat() Stream<Int>Stream<Long>,那么concat()将返回一个Stream<Number>

如果您concat()两个元素之间没有关系的流(如Stream<String>Stream<Long> ),那么concat()将返回一个Stream<Object>。这就是在您的代码中发生的事情,因为MyClassMyInterface彼此之间没有任何关系,除了以Object作为父级之外。

它看起来像是在隐式地将筛选器的返回类型转换为Stream,这会导致Stream.concat返回预期的类型。

这个解释看起来很诱人,因为它似乎符合事实,但是如果您的过滤器中的谓词被更改为测试Runnable而不是MyInterface,会发生什么呢?

代码语言:javascript
复制
Stream<MyInterface> concatenation2 = Stream.concat(
    myClassStream.filter(element -> element instanceof Runnable),
    myInterfaceStream);

代码仍然编译,工具提示不变,因此筛选显然不会影响返回类型。换句话说,concat()的第一个参数将返回一个Stream<MyClass>,而不管在filter()中做什么。过滤器保证它也只返回MyInterface元素这一事实与此无关,但它似乎很重要,因为从concat()接收流的变量的类型是Stream<MyInterface>

如果从concat()接收流的变量的类型从MyInterface变为荒谬和无意义的东西(如Deque<LocalDateTime>),会发生什么?

代码语言:javascript
复制
Stream<Deque<LocalDateTime>> concatenation3 = Stream.concat(
    myClassStream.filter(element -> element instanceof MyInterface),
    myInterfaceStream);

有两件事值得注意:

  • 尽管这段代码显然是无效的,但它仍然是在氧气(但不是光子)上编译的。
  • concat()的工具提示现在显示其返回类型为Stream<Deque<LocalDateTime>>,这显然是没有意义的。

为什么这段代码会中断?我怎么会有以前的行为?

氧气的编译器允许使用Stream.concat()进行无效的变量定义,这似乎在光子中得到了修正。您不应该希望以前的行为,因为它是不正确的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51399466

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档