gpt4 book ai didi

java - 简单参数的堆污染

转载 作者:行者123 更新时间:2023-11-30 06:06:16 25 4
gpt4 key购买 nike

我有以下功能:

public static <T> List<T> list(T... xs) {
final List<T> lst = new ArrayList<T>();
for (final T x : xs) {
lst.add(x);
}

return lst;
}

它的用法很简单:

   List<Integer> ints = list(1, 2, 3, 4)

编译器给出了这个列表的以下警告

"TypeSafety: potential heap pollution for via varargs parameter

我试图找到它的含义,但我发现的所有解释都是针对本身参数化的参数函数,例如

f(列表 ... xss)。

虽然我有通用非参数化参数的功能。

请解释我的函数有什么潜在问题,因为我找不到任何问题。

最佳答案

Java 中的 Varargs 是一种语法糖。 T... xsT[] xs相同.因此实际上你有一个带有参数化参数(数组)的函数。

回到你的问题。让我们考虑一下这种情况,当你通过 List<String>作为方法的通用类型。然后你有一个元素数组 List<String>作为你的方法的参数。因此出现了两个重要问题,并导致代码中可能存在缺陷。

  1. 数组是协变的,这意味着编译器将允许这样的赋值:Object[] arr = xs
  2. 由于编译期间的一般删除,数组包含原始 List元素,不幸的是,Java 无法保证您放入数组中的元素恰好是 List<String>。 .所以如果你把 List<Integer> java.lang.ArrayStoreException不会在运行时抛出。

这一切都会导致您可能产生堆污染的情况。请看下面的例子:

public static <T> List<T> list(T... xs) {
final List<T> lst = new ArrayList<T>();
for (final T x : xs) {
lst.add(x);
}
Object[] arr = xs; //arrays are covariant, we can do this
arr[0] = Arrays.asList(4); //<--------heap pollution
return lst;
}
public static void main(String[] args) {
List[] arr = { Arrays.asList("one"), Arrays.asList("two"), Arrays.asList("three") };
List<List<String>> l = list(arr);
for (List list : arr) {
System.out.println(list.get(0));
}
}

输出:

4
two
three

这里有一个关于这个主题的很好的解释: http://www.angelikalanger.com/GenericsFAQ/FAQSections/ProgrammingIdioms.html#FAQ300

官方 Java 指南: https://docs.oracle.com/javase/8/docs/technotes/guides/language/non-reifiable-varargs.html

关于java - 简单参数的堆污染,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44409790/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com