我终于试图摆脱Java 7所产生的所有新编译器警告。我这两个人离开了,我无法理解。有没有办法摆脱它们而不压制它们?
构造一般类型对象的数组(我可以在数组中创建一个?):
static final int N = 10;
//warning: [unchecked] unchecked conversion
static final Set<Widget>[] queued = new ConcurrentSkipListSet[N];
//required: Set<Widget>[]
//found: ConcurrentSkipListSet[]
Generic varargs(似乎几乎无处不在,我接受泛型类型的varargs):
class Foo<T> {
//warning: [unchecked] Possible heap pollution from parameterized vararg type T
public void add(T... entries) {
//where T is a type-variable:
//T extends Object declared in class Foo
顺便说一句:我已经有了:
// Add many entries to the list.
public void add(List<T> entries) {
// ...
}
// Add a number of entries.
public void add(T... entries) {
// Make a list of them.
add(Arrays.<T>asList(entries));
}
答案 0 :(得分:7)
第一个:
static final Set<Widget>[] queued = new ConcurrentSkipListSet<>[N];
在Java 7之前,它必须是:
static final Set<Widget>[] queued = new ConcurrentSkipListSet<Widget>[N];
但是,最好将此声明为ArrayList<Set<Widget>>
。通常,混合数组和泛型在Java中有点困难。
static final List<Set<Widget>> queued = new ArrayList<>();
// or new ArrayList<Set<Widget>>();
关于第二个,请参阅this thread。虽然你可以压制消息,但它实际上警告了真正的危险。该线程的底线是,安全的做法是将您的方法签名(以及相应的调用)更改为:
class Foo<T> {
public void add(List<T> entries) {
. . .
问题基本上与第一个问题相同:你不应该创建泛型数组。
答案 1 :(得分:2)
要解决第二个问题,您需要将@SafeVarargs
添加到方法声明中。
从javadocs开始,这是:
程序员断言注释方法的主体或 构造函数不会对其执行潜在的不安全操作 varargs参数。将此批注应用于方法或构造函数 抑制关于不可恢复的变量arity的未经检查的警告 (vararg)键入并禁止有关参数化的未经检查的警告 在呼叫站点创建数组。
答案 2 :(得分:1)
关于通用varargs警告:
答案 3 :(得分:1)
通用数组创建:
static final ConcurrentSkipListSet<Widget>[] queued = newArray(N);
// note: declare the most specific type for private objects
@SafeVarargs
static <E> E[] newArray(int length, E... array)
{
return Arrays.copyOf(array, length);
}
它是如何工作的 - 因为newArray
是一个vararg方法,必须传入E[] array
参数,因此方法体可以访问类型E[]
。这在理论上是正确的,如果没有擦除,它在运行时将是完全类型安全的。通过擦除,我们在运行时只删除了E[]
类型,没关系,我们也返回相同的擦除类型。