我有一个像下面这样的构造函数
public MyConstructor(MyObject<T> ... objects) {
// ...
}
Eclipse 用以下消息警告我:
类型安全:通过可变参数对象的潜在堆污染
我像这样更改构造函数:
public MyConstructor(MyObject<T>[] objects) {
// ...
}
现在,警告消失了。但是,我认为潜在的危险并没有解决。
这种解决方法有效吗?
我有一个像下面这样的构造函数
public MyConstructor(MyObject<T> ... objects) {
// ...
}
Eclipse 用以下消息警告我:
类型安全:通过可变参数对象的潜在堆污染
我像这样更改构造函数:
public MyConstructor(MyObject<T>[] objects) {
// ...
}
现在,警告消失了。但是,我认为潜在的危险并没有解决。
这种解决方法有效吗?
在某种程度上,这是一种解决方法。创建不可具体化组件类型的数组是不安全的。因此编译器不允许这样的数组创建表达式:
// 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 };
Arrays.asList
但是,允许通过可变数量方法(例如 )创建隐藏数组。
// RHS amounts to Arrays.asList(new List<String>[] { null, null })
List<List<String>> example = Arrays.asList(null, null);
由于您不允许创建此数组,因此您的堆不能再被污染。但是:您将如何调用该构造函数?
请注意,您的构造函数可能根本不会污染堆。它的唯一方法是如果
MyObject<?>[]
or Object[]
)或如果您都不这样做,则可以将构造函数标记为具有@SafeVarargs
并且警告消失。
但是,由于类型擦除,编译器将可变参数形式参数转换为
Object[]
元素。因此,存在堆污染的 可能性。
我们知道这个警告的原因主要基于类型擦除,现在它在 Java Docs for Heap Pollution中明确指出,
如果您确保您的代码在没有警告的情况下编译,则不会发生堆污染。
还有更多关于这个
List<String>... l
编译器在将 varargs 形式参数转换为形式 参数时已生成警告List[] l
。本声明有效;变量 l 的类型List[]
是 ,它是 的子类型Object[]
。
以便
因此,如果将任何类型的 List 对象分配给 objectArray 数组的任何数组组件,编译器不会发出警告或错误。
所有引用的语句均从 Java Doc 复制