gpt4 book ai didi

java - 可变参数堆污染 : what's the big deal?

转载 作者:IT王子 更新时间:2023-10-28 23:29:56 25 4
gpt4 key购买 nike

我正在阅读 varargs heap pollution而且我真的不明白 varargs 或不可具体化类型将如何对没有通用性的情况下不存在的问题负责。确实,我可以很容易地替换

public static void faultyMethod(List<String>... l) {
Object[] objectArray = l; // Valid
objectArray[0] = Arrays.asList(42);
String s = l[0].get(0); // ClassCastException thrown here
}

public static void faultyMethod(String... l) {
Object[] objectArray = l; // Valid
objectArray[0] = 42; // ArrayStoreException thrown here
String s = l[0];
}

第二个简单地使用了数组的协方差,这确实是这里的问题。 (即使 List<String> 是可具体化的,我想它仍然是 Object 的子类,我仍然可以将任何对象分配给数组。)当然我可以看到两者之间有一点区别,但是无论是否使用泛型,这段代码都是错误的。

堆污染是什么意思(这让我想到了内存使用,但他们谈论的唯一问题是潜在的类型不安全),以及它与使用数组的任何类型违规有何不同协方差?

最佳答案

您说得对,常见的(和基本的)问题在于数组的协方差。但是在你给出的这两个例子中,第一个更危险,因为它可以修改你的数据结构并将它们置于稍后会中断的状态。

考虑您的第一个示例是否触发了 ClassCastException:

public static void faultyMethod(List<String>... l) {
Object[] objectArray = l; // Valid
objectArray[0] = Arrays.asList(42); // Also valid
}

以下是有人使用它的方式:

List<String> firstList = Arrays.asList("hello", "world");
List<String> secondList = Arrays.asList("hello", "dolly");
faultyMethod(firstList, secondList);
return secondList.isEmpty()
? firstList
: secondList;

所以现在我们有一个 List<String>实际上包含 Integer ,它安全地漂浮着。在稍后的某个时刻——可能更晚,如果它被序列化,可能很多更晚并且在不同的 JVM 中——终于有人执行 String s = theList.get(0) .此故障与导致它的原因相距甚远,因此可能很难追查。

请注意,ClassCastException 的堆栈跟踪并没有告诉我们错误真正发生在哪里;它只是告诉我们是谁触发了它。换句话说,它并没有为我们提供太多关于如何修复错误的信息。这就是它比 ArrayStoreException 更重要的原因。

关于java - 可变参数堆污染 : what's the big deal?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32291515/

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