为什么Java编译器允许重用流?
让我们想象一下以下代码:为什么Java编译器允许重用流?,java,java-stream,illegalstateexception,Java,Java Stream,Illegalstateexception,让我们想象一下以下代码: Stream<Integer> numberStream = ...; Predicate<Integer> isEven = ...; Predicate<Integer> isOdd = ...; List<Integer> evenNumbers = numberStream .filter(isEven) .collect(Collectors.toList()); List<Integ
Stream<Integer> numberStream = ...;
Predicate<Integer> isEven = ...;
Predicate<Integer> isOdd = ...;
List<Integer> evenNumbers = numberStream
.filter(isEven)
.collect(Collectors.toList());
List<Integer> oddNumbers = numberStream
.filter(isOdd)
.collect(Collectors.toList()); // this line will throw IllegalStateException
streamnumberstream=。。。;
谓词isEven=。。。;
谓词isOdd=。。。;
列表编号=numberStream
.过滤器(isEven)
.collect(Collectors.toList());
列表编号=numberStream
.过滤器(isOdd)
.collect(Collectors.toList());//此行将抛出IllegalStateException
以上代码编译时没有任何警告。但是,尝试运行它将始终导致非法状态异常
在研究它之后,我发现一个流
只能有一个终端操作,因此基本上没有必要将它存储在变量中
在我看来,这将是一个非常容易被编译器发现的错误。为什么它编译时没有错误?有没有这样的代码有用的用例?从某种意义上说,编译器很简单 它根据Java语言的规则验证您的代码是合法的,并且您的所有调用都符合Java语言规则和类型系统的要求 无论是语言规则还是类型系统都无法“编码”不能重用的
流。这只是编译器不知道的一个事实
将streams视为构建在Java之上的特定于领域的语言。编译器只知道该概念中较低的“Java”层,但不理解较高级别的流“语言”的规则
因此,虽然可以想象编译器会被告知特定语言的规则,但这是一条危险的道路,因为有很多领域特定的语言,人们可以想象,想要验证这些语言,并且把它们做好是。。。不太可能。简短回答:流不能重用的事实没有(也不能)在Java类型系统中编码。编译器对流一无所知(除了所使用的类)。编译器会检查您编写的代码是否符合Java语言定义的规范。但它不会检查代码在应用意义上是否正确。我认为您正在为IDE或maven/gradle构建寻找java linter插件。声纳也可能是一种选择