2013-03-21 59 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.