这是堆污染吗?

Ste*_*han 7 java generics variadic-functions heap-pollution

我有一个像下面这样的构造函数

public MyConstructor(MyObject<T> ... objects) {
     // ...
}
Run Code Online (Sandbox Code Playgroud)

Eclipse通过以下消息警告我:

类型安全:通过varargs参数对象潜在的堆污染

我改变了这样的构造函数:

public MyConstructor(MyObject<T>[] objects) {
     // ...
}
Run Code Online (Sandbox Code Playgroud)

现在,警告消失了.但是,我认为潜在的危险并未解决.

这种解决方法有效吗?

Ben*_*ulz 6

在某种程度上它是一种解决方法.创建不可重新组件类型的数组是不安全的.因此编译器不允许这样的数组创建表达式:

// List<String> is erased to List => disallowed
Object example = new List<String>[] { null, null };

// List<?> is effectively reifiable => allowed
Object example = new List<?>[] { null, null };
Run Code Online (Sandbox Code Playgroud)

然而,Arrays.asList允许通过诸如变量arity方法的隐藏数组创建.

// RHS amounts to Arrays.asList(new List<String>[] { null, null })
List<List<String>> example = Arrays.asList(null, null);
Run Code Online (Sandbox Code Playgroud)

由于您不允许创建此数组,因此您的堆不再受到污染.但是:你怎么会打电话给那个构造函数?

请注意,您的构造函数可能根本不会污染堆.它唯一的方法是

  • 它将数组转换为不太具体的类型(即MyObject<?>[]Object[])或
  • 它让数组以某种方式转义(即将它分配给一个字段并从getter返回或将其传递给一个可能不安全的方法).

如果你不这样做,你可以将构造函数标记为有@SafeVarargs,并且警告消失.