Java EclipseNull分析为类文本发出null类型安全警告
考虑启用了空分析的Eclipse项目的以下部分内容: 适用于64位Windows的Eclipse Mars版本(4.5.0;20150621-1200)Java EclipseNull分析为类文本发出null类型安全警告,java,eclipse,null,annotations,eclipse-jdt,Java,Eclipse,Null,Annotations,Eclipse Jdt,考虑启用了空分析的Eclipse项目的以下部分内容: 适用于64位Windows的Eclipse Mars版本(4.5.0;20150621-1200) Oracle JDK 1.8.0_60 package info.java @org.eclipse.jdt.annotation.NonNullByDefault package bar; package bar; public class Foo { public static void main(String[] args)
Oracle JDK 1.8.0_60 package info.java
@org.eclipse.jdt.annotation.NonNullByDefault
package bar;
package bar;
public class Foo {
public static void main(String[] args) {
}
}
class Base<T> {
private final Class<T> type;
public Base(Class<T> type) {
this.type = type;
}
public Class<T> getType() {
return this.type;
}
}
class Derived extends Base<String> {
public Derived() {
super(String.class); // <-- Null type safety warning here
}
}
Foo.java
@org.eclipse.jdt.annotation.NonNullByDefault
package bar;
package bar;
public class Foo {
public static void main(String[] args) {
}
}
class Base<T> {
private final Class<T> type;
public Base(Class<T> type) {
this.type = type;
}
public Class<T> getType() {
return this.type;
}
}
class Derived extends Base<String> {
public Derived() {
super(String.class); // <-- Null type safety warning here
}
}
避免此警告的正确方法是什么?您看到的冲突是类型参数之间的冲突
- 。。。所需类型的:
@非空字符串
- 。。。提供的类型:
String
extends Base
,在@NonNullByDefault
的机制下,它被扩展为extends Base
。从这里开始,它一直渗透到超级构造函数,在类型参数替换后将其签名呈现为(@NonNull Class)
。相反,类文本被编译器视为具有类型@NonNull class
,这是不兼容的
真正的解决方案将通过,具体见评论3 f中的讨论
目前(使用EclipseMars),您可能必须减少@NonNullByDefault
的影响,以便接受@nonNullClass
。这可以通过在类Derived
之上的更具体的@NNBD声明来实现,如下所示
import static org.eclipse.jdt.annotation.DefaultLocation.*;
...
@NonNullByDefault({PARAMETER, RETURN_TYPE, FIELD, TYPE_BOUND})
class Derived extends Base<String> {
...
import static org.eclipse.jdt.annotation.DefaultLocation.*;
...
@NonNullByDefault({参数,返回类型,字段,类型绑定})
类派生的扩展基{
...
在这里,我们利用了一个事实,@NNBD可以根据其应用的位置进行微调。在这个声明中,无参数的@NonNullByDefault
的区别在于省略了位置TYPE_参数
,这意味着扩展基
中的String
将不再像因此,超级构造函数现在将具有以下签名:(@NonNull Class)
,并且所有编译都没有警告
通过将经过微调的@NNBD放在类
派生的上,此解决方法的范围尽可能小。谢谢,Stephan。很抱歉在创建此问题之前没有返回并进行回顾。否则,我会看到您和Udo之间在创建错误af之后进行的额外讨论回答我之前的问题。有了这些信息,我就能够推断出你的解决方法,并为你节省了一些时间。:-)n.p.-希望这个答案将来对其他人也有帮助:)修复对于477719,假设T.class
属于class
类型有点奇怪。这会导致明显错误的语句,如@NonNull String s=String.class.cast(null);
在没有警告的情况下通过。或者通常,它似乎假设任何方法使用类
并返回X
以返回非空值。只要系统库没有空注释,使用泛型库类不可避免地是一条崎岖不平的道路。请参阅Class.cast()的javadoc:“@在强制转换后返回对象,如果obj为null,则返回null”。因此,该方法应具有签名@Nullable T cast(@Nullable object)
,编译器将正确地分析您的代码段。幸运的是,外部注释允许您准确地进行分析。我同意将该类型参数硬编码为非空的选择有点随意,但我相信当时我们有充分的理由。不可能将此选项传递给用户。@StephanHerrmann我刚刚发现我遇到这个问题的项目还有另一个问题:当自定义注释具有@Retention(RetentionPolicy.SOURCE)
时,即使所有涉及的类都在源代码中,它也不起作用。我可以接受它,但我认为Eclipse应该发出一个关于不受支持的@Retention
的警告。