2013-03-21 107 views
6

我终于试图摆脱Java 7友好生成的所有新的编译器警告。我留下这两个我无法理解。有没有办法摆脱它们而不压制它们?一些Java 7的警告 - 如何删除它们

构建一般类型对象的数组(我在哪里可以把在创建阵列?):

static final int N = 10; 
//warning: [unchecked] unchecked conversion 
    static final Set<Widget>[] queued = new ConcurrentSkipListSet[N]; 
//required: Set<Widget>[] 
//found: ConcurrentSkipListSet[] 

通用可变参数(好像几乎无处不在我接受泛型类型的可变参数发生):

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 

BTW:我已经有:

// 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)); 
    } 

回答

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是一个可变参数的方法,一个E[] array参数必须传递,因此方法体中可以访问的E[]类型。这在理论上是正确的,如果没有擦除,它将在运行时完全安全。擦除后,我们只在运行时擦除了E[],这很好,我们也会返回相同的擦除类型。

+0

哇!一举解决了我的问题。我不明白'newArray(N)'实际上是如何将一个正确类型的数组传递给'newArray',而是向您传达您的先生。顺便说一句 - 我把它调整为static final ConcurrentSkipListSet [] queued = DoubleBufferedList。> newArray(N);'为我的测试。 – OldCurmudgeon 2013-03-22 10:27:03

+0

为什么不简单'static final ConcurrentSkipListSet [] queued = DoubleBufferedList.newArray(N);' – ZhongYu 2013-03-22 11:13:03

+0

因为当我追踪到它的形式给了我一个Object []'在第二个参数。我有一个'ConcurrentSkipListSet []',对我来说感觉更好。我意识到这是一个非常小的差异,因为它们基本上都是Object []'。 – OldCurmudgeon 2013-03-22 11:43:39

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) { 
     . . . 

的问题是基本相同的第一:你不应该创建数组泛型。

+0

我已经尝试了这两个 - 我得到了'错误:通用数组创建'在这两种情况下。 – OldCurmudgeon 2013-03-21 16:07:52

+0

@OldCurmudgeon - 我修改了一下我的答案。使用'ArrayList >'。 – 2013-03-21 16:08:23

+0

您的参考资料最终指向讨论该问题的Oracle页面,但我没有在那里找到解决方案。 – OldCurmudgeon 2013-03-21 16:10:24

2

要解决第二个问题,您需要将@SafeVarargs添加到方法声明中。

javadocs,这就是:

A programmer assertion that the body of the annotated method or constructor does not perform potentially unsafe operations on its varargs parameter. Applying this annotation to a method or constructor suppresses unchecked warnings about a non-reifiable variable arity (vararg) type and suppresses unchecked warnings about parameterized array creation at call sites.