2017-06-21 140 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警告。