fin*_*nnw 5 java eclipse annotations nullable eclipse-jdt
当使用基于注释的空分析时,我会得到以下(令人困惑的)警告,其中涉及一个数组:
Null type safety (type annotations): The expression of type 'int[]' needs unchecked conversion to conform to 'int @Nullable[]'
当我将未注释int[]
的int @Nullable[]
参数传递给参数时会发生这种情况.
这是令人惊讶的.通常只有一个问题,如果你取一个可空的值并尝试将它传递给一个非空参数,但我正在做相反的事情 - 采用一个已知的非null(虽然没有注释)数组并将其传递给一个方法(Arrays.equals
)确实接受空值.
此外,它似乎不是非数组对象的问题.通常,T
可以将(未注释的,非数组)类型的变量或返回分配给a @Nullable T
.
所以我的问题是为什么在T
数组类型时这会改变?
我的类是一个可清除/可比较的代理,用于使用int[]
(取自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;
}
Run Code Online (Sandbox Code Playgroud)
package-info.java:
/**
* @author finnw
*
*/
@org.eclipse.jdt.annotation.NonNullByDefault
package example;
Run Code Online (Sandbox Code Playgroud)
Tag.java :(部分)
package other;
public class Tag {
public native int[] getUniqueIdentifier(); // Currently returns a fresh array on each call, but may change in the near future to reuse a single array
}
Run Code Online (Sandbox Code Playgroud)
public boolean hasMatchingIdentifier(@Nullable Object id) {
return id instanceof int[] &&
Arrays.equals(this.tag.getUniqueIdentifier(), (int[])id);
}
Run Code Online (Sandbox Code Playgroud)
我宁愿避免这些方法:
@SuppressWarnings("null")
到TagKey
或它的equals
方法(量产版是较为复杂和有尴尬的NPE的高风险.)笔记:
@Nullable int[] id
.令人惊讶的是,没有任何警告信息,即使它暗示原始int
元素可能null
明显错误.添加这个方法:
@SuppressWarnings("null")
public static int @Nullable[] getUniqueIdentifier(Tag tag) {
return tag.getUniqueIdentifier();
}
Run Code Online (Sandbox Code Playgroud)
然后:
return ((TagKey) obj).hasMatchingIdentifier(getUniqueIdentifier(this.tag));
Run Code Online (Sandbox Code Playgroud)
这就是为什么我忽略“来自非注释的未经检查的转换”警告,直到支持空配置文件为止,您要么在各处抑制空警告(这违背了要点),要么为每个库创建带注释的包装器方法。
归档时间: |
|
查看次数: |
471 次 |
最近记录: |