2017-06-21 153 views
4

下面是代碼:爲什麼@SafeVarargs不會抑制警告?

class Foo<T> { 
    private final T[] array; 
    @SafeVarargs 
    Foo(T... items) { 
    this.array = items; 
    } 
} 

我越來越:

[WARNING] Varargs method could cause heap pollution 
from non-reifiable varargs parameter items 

這有什麼錯我的任務?如何解決這個問題? @SuppressWarnings不是一個選項,因爲我想這個構造函數是真正的「安全」。

$ javac -version 
javac 1.8.0_40 
+0

改爲使用'List ';用'new Foo(Arrays.asList(...))'調用'。 –

+1

未收到任何有關javac或Netbeans或intellij的警告。使用eclipse? – assylias

+0

@assylias我用'-Xlint'編譯 – yegor256

回答

1

我的問題是我使用-Xlint命令行javac參數。我發現我必須用下列參數進行編譯:

javac -Werror -Xlint -Xlint:-varargs 

就是這樣。

1

約書亞·布洛克解釋這種有效的Java(25S章):

泛型數組創建禁止,可惱人的。這意味着,例如, 例如,一般類型 通常不可能返回其元素類型的數組(但請參閱條目29中的部分 解決方案)。這也意味着當 使用可變參數方法(第42項)與泛型類型組合時,您可能會產生混淆警告。 這是因爲每次調用可變參數方法時,都會創建一個數組 以容納可變參數參數。如果此 數組的元素類型不可確定,您將收到警告。除了壓制這些警告(項目24)和 之外,您幾乎無法對 這些警告進行操作,以避免在您的API中混用泛型和可變參數。

這樣做的原因的消息中spec被描述的,在規範的this部分,有類似的例子(與類ArrayBuilder和註解的使用的不同組合)

像替代方案中,嘗試使用SafeVarargs的混合和SuppressWarnings註釋

@SafeVarargs 
@SuppressWarnings("varargs") 

HTH

+5

您正在解釋**警告**。你**根本不會**回答爲什麼**註釋**不會抑制**警告的問題。但是,也許我錯了,一些upvoters可以解釋他們爲什麼認爲這個答案**回答**這個問題。 – GhostCat

+0

'@ SuppressWarnings'不是一個選項,因爲此ctor的所有其他調用仍將產生相同的警告。 – yegor256

1

docs

應用這個註釋的方法或構造抑制約非reifiable可變元數(可變參數)未選中的警告類型在調用位置抑制有關參數數組創建未經檢查的警告。

第一條語句告訴我們@SafeVarargs禁止有關unchecked警告:

  • 非reifiable類型的可變參數
  • 當你調用方法

在你的情況的參數數組創作,@SafeVarargs正在抑制T... items上的警告。您的警告發生在this.array = items;


JLS §9.6.4.7

註釋@SafeVarargs非本地影響,因爲它在方法調用抑制unchecked警告除了表達式到有關的一個選中警告變量arity方法本身的聲明


相比之下,註釋@SuppressWarnings("unchecked")有局部影響,因爲它只能抑制有關的方法的聲明unchecked警告。