gpt4 book ai didi

java - 没有明确声明泛型类型的赋值如何被滥用?

转载 作者:行者123 更新时间:2023-12-01 11:45:58 25 4
gpt4 key购买 nike

假设我有这个代码:

private Hashtable items = new Hashtable();

Eclipse 会针对此类分配发出警告,因为这是未经检查的、不安全的操作。

更好的解决方案是:

private Hashtable<String,String> items = new Hashtable<String,String>();

或者(如果我不确定类型)

private Hashtable<?,?> items = new Hashtable<?,?>();

不显式提供类型会产生什么后果?从安全角度来看,这是否会被滥用?这可以在测试中捕获吗(我必须使用反射吗?)以及如何捕获?

最佳答案

通过使用原始类型,编译器不能阻止您将任何旧的键和值添加到映射中。如果您的键和值恰好是Object,那可能没问题。 s,但根据我的经验,这并不是很常见的事情。

通过使用显式类型界限,如果您尝试传入错误类型的参数,您的代码将无法编译。例如:

Map<String, String> genericMap = new HashMap<>();
genericMap.put(new Object(), new Object()); // compiler error.

但是,如果你要写:

Map rawMap = genericMap;
rawMap.put(new Object(), new Object()); // fine.

所以现在基本上所有关于该 map 中包含的内容的赌注都已结束。如果您通过genericMap到一个远程方法,期望 Map<String, String>并且将消耗其中的值,您将遇到运行时故障,可能是 ClassCastException :

import java.util.HashMap;
import java.util.Map;

class DontDoThis {
@SuppressWarnings("unchecked")
public static void main(String[] args) {
Map<String, String> genericMap = new HashMap<>();
Map rawMap = genericMap;
rawMap.put(new Object(), new Object());
useMap(genericMap);
}

private static void useMap(Map<String, String> map) {
for (String key : map.keySet()) {} // ClassCastException.
}
}

如果您使用通配符边界,则无法执行诸如将新值放入 map 之类的操作:

Map<?, ?> wildcardMap = genericMap;
genericMap.put("key1", "value1"); // fine.
wildcardMap.put("key", "value"); // compiler error.

但是,您仍然可以使用 wildcardMap 中的值;您所能知道的只是这些值是 Object 的子类型:

for (Map.Entry<?, ?> entry : wildcardMap.entrySet()) {
Object key = entry.getKey();
Object value = entry.getValue();

// Use key and value somehow.
}
<小时/>

至于如何在测试中捕获它的问题 - 你不应该为这种东西编写测试 - 成功的编译就是你的测试!

编译时类型安全为您提供的覆盖范围比您实际希望编写的任何测试都要大得多,而且代码要少得多。

关于java - 没有明确声明泛型类型的赋值如何被滥用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29121315/

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