简体   繁体   English

为什么 Java 编译器允许重用 Stream?

[英]Why does Java compiler allow to reuse a Stream?

Let's imagine the following code:让我们想象下面的代码:

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

The above code compiles without any warnings.上面的代码编译没有任何警告。 However, trying to run it will always result in an IllegalStateException .但是,尝试运行它总是会导致IllegalStateException

After looking into it, I found out that one Stream can only have one terminal operation, so basically there is no point in storing it inside a variable.查了一下,发现一个Stream只能有一个终端操作,所以把它放在变量里面基本上没有意义。

It seems to me that this would be a very easy error to spot by the compiler.在我看来,这将是编译器很容易发现的错误。 Why does it compile without errors?为什么它编译没有错误? Is there some use case where code like that would be useful?有没有这样的代码有用的用例?

The compiler is simple, in a sense.从某种意义上说,编译器很简单。

It verifies that your code is legal according to the rules of the Java language and that all your calls match what the Java language rules and type system requires.它根据 Java 语言的规则验证您的代码是否合法,并且您的所有调用都符合 Java 语言规则和类型系统要求的内容。

Neither the language rule nor the type system somehow "encodes" that a Stream can not be reused.语言规则类型系统都不能以某种方式“编码” Stream不能被重用。 It's simply a fact that the compiler doesn't know about.这只是编译器不知道的事实。

Think of streams as a domain-specific language built on top of Java.将流视为构建在 Java 之上的特定领域语言。 The compiler only knows the lower "Java" layer of that concept, but doesn't understand the rules of the higher-level Streams "language".编译器只知道该概念的较低“Java”层,但不了解较高级别 Streams“语言”的规则。

So while the compiler could conceivably be told about the rules of that specific language, this is a dangerous road to go, because there are many, many domain specific languages like that which one could conceivably want to verify and doing them all right is... unlikely.因此,尽管编译器可能会被告知该特定语言的规则,但这是通往 go 的危险道路,因为有很多很多特定领域的语言,就像人们可以想象的那样想要验证并正确处理它们是...... . 不太可能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么Java编译器有时允许取消装箱为空? - Why does the Java compiler sometimes allow the unboxing of null? 为什么 java 允许这样做? - why does java allow this? Java编译器是否优化了流过滤? - Does Java compiler optimize stream filtering? 为什么Java编译器允许在三元运算符中将null转换为基本类型 - Why does Java compiler allow casting null to primitive type in ternary operator 如果结果必须是 int,为什么 Java 编译器允许 int/int 除法? - Why does the Java compiler allow int/int division if the result must be an int? 为什么Java编译器允许在throws部分中列出异常,而方法无法抛出该异常 - Why does the Java compiler allow exceptions to be listed in the throws section that it is impossible for the method to throw 为什么java允许NPE - Why does java allow NPE Gradle不允许添加&#39;-processor&#39;Java(1.8)编译器参数 - Gradle does not allow to add '-processor' java(1.8) compiler args 当方法永远不会抛出异常时,为什么编译器允许抛出 - Why does the compiler allow throws when the method will never throw the Exception 为什么Java编译器不对数组进行实习? - Why java compiler does not interns arrays?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM