我在使用 Oracle java 8u25 的 Windows 7 64 位上的 Spring 工具套件 3.6.2(Eclipse clon)下遇到了 nullcheck 分析的奇怪行为。同一个java 7源码兼容的maven项目在eclipse中成功发现NPE错误,但是当我在maven中将编译版本改为java 1.8时,eclipse无法发现这个错误。
我在Eclipse中的nullcheck分析配置(Java->Compiler->Errors/Warnings->Null analysis)是: 在 null 分析中包含断言 true 启用基于注释的分析 true NotNull 自定义注释已正确设置为 javax.validation.constraints.NotNull 等等(一切似乎都很好,因为它在 java 7 下工作)
我的 maven pom 在这里 http://pastebin.com/pF1yJSG2 ,如前所述,当pom中的java.version为1.7时,空检查有效,当为1.8时,空检查无效。
示例源代码是:
package test.nullcheckbug.core;
import javax.validation.constraints.NotNull;
public class Program {
/**
* This will fail to compile under java 7 (null analysis works in STS
* 3.6.2). But under java 8 it does not show error in Eclipse Markers -
* static analysis does not work ?!
*
* @return null which is not allowed
*/
@NotNull
public String fail() {
return null;
}
/**
* Simple main.
*
* @param args
* ignored args
*/
public static void main(String[] args) {
}
}
有人知道问题出在哪里以及如何在 jdk 1.8 兼容性下启用 nullcheck 吗?
编辑: Maven似乎没有参与。在具有相同源代码和编译器兼容级别设置为 1.7 的非 maven 项目上模拟了相同的问题。是错误吗?
EDITED-2: 经过更多检查后,我发现注释中的以下差异会产生差异:java.lang.annotation.ElementType.TYPE_USE,当注释没有此内容时,在 Java 8 下未检测到 nullcheck,但在 Java 7 下检测到。 但为什么 ?!为什么会有如此不同的行为?!
EDITED-3: 经过 MartinLippert 的研究和我的测试,nullcheck API 似乎在 java 7 和 java 8 之间发生了巨大变化。空检测需要(从 eclipse 库的 2.0 版可以看出)java.lang.annotation.ElementType.TYPE_USE,@Target 类型(value={METHOD,FIELD,ANNOTATION_TYPE,CONSTRUCTOR,PARAMETER}) 在分析中被忽略。所以现在的问题如下:为什么 JAVA 8 下的 NULL 分析需要并且只能在新的元素类型下工作? (我知道使用 Java 8 可以充分利用新的语言特性,但为什么需要破坏兼容性?例如 javax.validation @NotNull 现在不能用作空检查注释:-((()
最佳答案
对于 Eclipse Luna,开发工作集中在“典型”组合上:
- Java 7 和声明注释
- Java 8 和类型注释
在这个版本中,Java 8 和声明注释的组合(在这个问题中要求的)没有完全实现。 这已通过 https://bugs.eclipse.org/bugs/show_bug.cgi?id=435805 修复
自 M4 以来,针对 Eclipse Mars 的里程碑构建中提供了此修复程序。
OTOH,我只能鼓励使用 Java 8 的项目升级到类型注释以获得更强的表现力——实现更精确的 null 类型检查。
关于java - 7 和 8 之间的 Eclipse 兼容性中断中的空分析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27041741/