简体   繁体   中英

Ternary operator does not recognize compile error in Eclipse

I am using Eclipse as the IDE and had this below code

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. I have tried the latest eclipse version Photon as well and it is still the same.

But when I use Jenkins to build the project, it is throwing the proper compile error. 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. 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 . It only affects Java 8, so using a different version solves the problem.

Note that while a construct like 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 ? : 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 ”¹

¹ I deliberately linked to the Java 8 version of the specification, which is the version where javac exhibits this wrong behavior.

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:

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 . 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.

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.

Likewise,

Integer variable = 42;
Long other = variable;

is not a valid assignment, but

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

is.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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