简体   繁体   English

三元运算符无法识别Eclipse中的编译错误

[英]Ternary operator does not recognize compile error in Eclipse

I am using Eclipse as the IDE and had this below code 我正在使用Eclipse作为IDE,并具有以下代码

List<Long> countList = new ArrayList<>();
Long count = (countList != null && !countList.isEmpty()) ? countList.get(0) : 0;

In Eclipse, the auto boxing for the else should produce a compile error but it is not. 在Eclipse中,else的自动装箱会产生编译错误,但不会。 I have tried the latest eclipse version Photon as well and it is still the same. 我也尝试了最新的Eclipse版本Photon,但仍然相同。

But when I use Jenkins to build the project, it is throwing the proper compile error. 但是,当我使用Jenkins构建项目时,它会抛出适当的编译错误。 Can some one advise, how to fix this issue? 有人可以建议如何解决此问题吗?

I tried the Setting Preferences -> Errors/Warnings -> Boxing and unboxing conversions and turned the default behavior from warning to error. 我尝试了设置Preferences -> Errors/Warnings -> Boxing and unboxing conversions ,并将默认行为从警告变为错误。 But this results in other unnecessary errors as well. 但这也会导致其他不必要的错误。

Is there a way to fix only this issue via an eclipse setting? 有没有一种方法可以通过日食设置解决此问题?

This is not a bug in Eclipse, but in javac . 这不是Eclipse中的错误,而是javac的错误。 It only affects Java 8, so using a different version solves the problem. 它仅影响Java 8,因此使用其他版本可以解决此问题。

Note that while a construct like Long var = 0; 注意,虽然像Long var = 0;这样的构造Long var = 0; is not allowed by the specification, conditional expressions are an entirely different field. 规范不允许,条件表达式是一个完全不同的字段。

The Java Language Specification's section about the “ Conditional Operator ? Java语言规范中有关“ 条件运算符? : has a notion of Numeric Conditional Expressions and even explicitly contains a conversion table showing that the combination of a 2nd argument of type Long and 3rd argument of type int should be valid, having a result type of “ bnp(Long,int) ”, whereas “bnp” stands for “ Binary Numeric Promotion ”¹ 具有数值条件表达式的概念,甚至显式包含一个转换表 ,该显示Long类型的第二个参数和int类型的第三个参数的组合应该是有效的,其结果类型为“ bnp(Long,int) ” ,而“ bnp”代表“ 二进制数字推广 ”¹

¹ I deliberately linked to the Java 8 version of the specification, which is the version where javac exhibits this wrong behavior. ¹我故意链接到规范的Java 8版本,该版本是javac表现出这种错误行为的版本。

In short, it implies unboxing, if needed, followed by widening primitive conversion, if needed, and finally, the result will be boxed again, if needed. 简而言之,这意味着在需要时取消装箱,然后在需要时扩大原始转换,最后,在需要时将结果再次装箱。

Note that even Java 8's javac does this correctly, as long as no generic methods are involved: 请注意,只要不涉及通用方法,即使Java 8的javac都能正确执行此操作:

Long boxed = !countList.isEmpty()? countList.get(0): null;
Long count = boxed != null? boxed: 0;// promotes int to Long

produces no compiler errors. 不产生编译器错误。

The behavior of producing compiler errors when generic methods are involved, has been described in JDK-8162708 Unexpected syntax error with ternary operator and generics methods . JDK-8162708中已描述了涉及泛型方法时产生编译器错误的行为, 以及三元运算符和泛型方法的意外语法错误 It also mentions that javac does handle this construct correctly under Java 7 and Java 9, so the problem only occurs in Java 8. I also just verified that the compiler error does not show up in the current state of Java 11 and Java 12. 它还提到javac确实在Java 7和Java 9下正确处理了此构造,因此问题仅在Java 8中发生。我还验证了在Java 11和Java 12的当前状态下未出现编译器错误。

It's worth pointing out that the rules described above may have counter-intuitive behavior. 值得指出的是,上述规则可能具有违反直觉的行为。 Eg 例如

boolean someCondition = true;
Long variable = null;
Long other = someCondition? variable: 0;

will throw a NullPointerException , as the reference stored in variable is not passed through, but will get unboxed and boxed again. 将抛出NullPointerException ,因为未传递存储在variable的引用,但将取消装箱并再次装箱。

Likewise, 同样,

Integer variable = 42;
Long other = variable;

is not a valid assignment, but 不是有效的分配,但

Integer variable = 42;
Long other = true? variable: 0L;

is. 是。

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM