Java 基于注释的空分析-警告仅与数组参数一起出现
在使用涉及数组的基于注释的空分析时,我收到以下(令人困惑的)警告:Java 基于注释的空分析-警告仅与数组参数一起出现,java,eclipse,annotations,nullable,eclipse-jdt,Java,Eclipse,Annotations,Nullable,Eclipse Jdt,在使用涉及数组的基于注释的空分析时,我收到以下(令人困惑的)警告: Null类型安全性(类型注释):类型“int[]”的表达式需要未经检查的转换才能符合“int@Nullable[]”的要求。 当我将未注释的int[]传递给int@Nullable[]参数时,就会发生这种情况 这是令人惊讶的。通常,只有当您获取一个可为null的值并尝试将其传递给一个非null参数时,这才是一个问题,但我正在做相反的事情——获取一个已知的非null(尽管没有注释)数组并将其传递给一个接受null的方法(Array
Null类型安全性(类型注释):类型“int[]”的表达式需要未经检查的转换才能符合“int@Nullable[]”的要求。
当我将未注释的int[]
传递给int@Nullable[]
参数时,就会发生这种情况
这是令人惊讶的。通常,只有当您获取一个可为null的值并尝试将其传递给一个非null参数时,这才是一个问题,但我正在做相反的事情——获取一个已知的非null(尽管没有注释)数组并将其传递给一个接受null的方法(Arrays.equals
)
另外,对于非数组对象,这似乎不是问题。通常,可以将一个变量或返回(未注记、非数组)类型T
分配给@Nullable T
所以我的问题是当T
是数组类型时,为什么会发生这种变化
我的类是一个haseab/Auto可比较的代理,它使用一个原生类,使用了<代码> int []/COD>(从C++函数中获取)作为唯一标识符。我的包使用基于注释的空分析,而第三方包(带有本机类)不使用
以下是显示问题的简化版本: TagKey.java:package example;
import java.util.Arrays;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import other.Tag;
import com.google.common.collect.Interner;
import com.google.common.collect.Interners;
public class TagKey {
private TagKey(Tag tag) {
this.tag = tag;
}
public static TagKey forTag(Tag tag) {
TagKey candidateKey = new TagKey(tag);
return INTERNER.intern(candidateKey);
}
@Override
public int hashCode() {
return Arrays.hashCode(this.tag.getUniqueIdentifier());
}
@Override
public boolean equals(@Nullable Object obj) {
if (this == obj) {
return true;
} else if (obj == null) {
return false;
} else if (getClass() != obj.getClass()) {
return false;
} else {
return ((TagKey) obj).hasMatchingIdentifier(this.tag.getUniqueIdentifier()); // Warning appears here
}
}
public boolean hasMatchingIdentifier(int @Nullable[] id) {
return Arrays.equals(this.tag.getUniqueIdentifier(), id);
}
@SuppressWarnings("null") // Guava cannot use type parameter annotations due to backward compatibility with Java 6
private static final Interner<TagKey> INTERNER = Interners.newWeakInterner();
private final Tag tag;
}
/**
* @author finnw
*
*/
@org.eclipse.jdt.annotation.NonNullByDefault
package example;
Tag.java:(部分)
我当前使用的变通方法: 我宁愿避免这些方法:
- 将
添加到@SuppressWarnings(“null”)
或其TagKey
方法(生产版本稍微复杂一些,并且有让NPE尴尬的高风险。)equals
注:
- 我的JDT版本是3.10.0.v20140606-1215
- 早些时候,我犯了一个错误,声明了
。令人惊讶的是,没有关于这一点的警告消息,即使它暗示原语@Nullable int[]id
元素可能是int
,这显然是错误的null
@SuppressWarnings("null")
public static int @Nullable[] getUniqueIdentifier(Tag tag) {
return tag.getUniqueIdentifier();
}
然后:
这就是为什么我会忽略“未经检查的非注释转换”警告,直到支持空值配置文件,否则您要么到处抑制空值警告(这违背了这一点),要么为每个库创建带注释的包装方法。任何由数组检查的数组。equals可以处理空值。您之前说的@Nullable int[]id是正确的,因为@Nullable没有定义数组中的项可以为null,它定义了参数(对象引用)可以为null。equals(null,null)返回true
private int[] a = null;
是完全合理的代码。因此,您要检查的是数组引用是否匹配,如果所有元素都相互匹配,或者如果两个引用都为null,则为true。如果变量声明为int[],根据定义,其内部成员不能为null。也就是说,上述代码是合法的,这不是:
a[0] = null;
如果它被定义为Integer[],当然会有所不同,但它不是。谢谢,但我真的不想这样做,因为我不确定它是否比
hasMatchingIdentifier(@Nullable Object)
有所改进。你知道为什么数组和非数组对象的行为不同吗?+1反正我认为你是对的,ABNA还不够成熟,还不能用于生产代码。但是我想知道谁会自愿为整个JRE创建空性配置文件。空性配置文件,也称为外部注释,将在EclipseMars(4.5)中得到支持。没有人使用JRE的整个API——只添加几个外部注释通常会对完全空检查的项目大有帮助-
return ((TagKey) obj).hasMatchingIdentifier(getUniqueIdentifier(this.tag));
private int[] a = null;
a[0] = null;