我使用Eclipse作为IDE,并在下面的代码中添加了
List<Long> countList = new ArrayList<>();
Long count = (countList != null && !countList.isEmpty()) ? countList.get(0) : 0;
在Eclipse中,else的自动装箱会产生编译错误,但不会。我也尝试了最新的Eclipse版本Photon,但仍然相同。
但是当我使用Jenkins构建项目时,它会抛出适当的编译错误。有人可以建议如何解决此问题吗?
我尝试了设置Preferences -> Errors/Warnings -> Boxing and unboxing conversions
,并将默认行为从警告变为错误。但这也会导致其他不必要的错误。
是否有一种方法可以通过日食设置来解决此问题?
答案 0 :(得分:3)
这不是Eclipse中的错误,而是javac
中的错误。它只会影响Java 8,因此使用其他版本可以解决问题。
请注意,虽然规范中不允许使用Long var = 0;
之类的构造,但条件表达式是一个完全不同的字段。
Java语言规范的section about the “Conditional Operator ? :”具有数值条件表达式的概念,甚至显式包含一个conversion table,表明{{1}类型的第二个参数的组合}和类型Long
的第三个参数应该是有效的,其结果类型为“ int
”,而“ bnp”代表“ Binary Numeric Promotion”¹
¹我故意链接到规范的Java 8版本,该版本是bnp(Long,int)
表现出这种错误行为的版本。
简而言之,它意味着在需要时取消装箱,然后在需要时扩大原始转换,最后,如果需要,将再次装箱结果。
请注意,只要不涉及通用方法,即使Java 8的javac
也会正确地做到这一点:
javac
不产生编译器错误。
JDK-8162708 Unexpected syntax error with ternary operator and generics methods中已描述了涉及泛型方法时产生编译器错误的行为。它还提到Long boxed = !countList.isEmpty()? countList.get(0): null;
Long count = boxed != null? boxed: 0;// promotes int to Long
确实在Java 7和Java 9下正确处理了此构造,因此问题仅出现在Java 8中。我还验证了编译器错误在Java 11和Java的当前状态下没有出现。 Java 12。
值得指出的是,上述规则可能具有违反直觉的行为。例如
javac
将抛出boolean someCondition = true;
Long variable = null;
Long other = someCondition? variable: 0;
,因为存储在NullPointerException
中的引用未通过,但将被取消装箱并再次装箱。
同样,
variable
不是有效的分配,但是
Integer variable = 42;
Long other = variable;
是。