java - 奇怪的 Java 类型安全不适用于集合
问题描述
public static <T> List<T> toArray(JSONArray array) {
if(array == null) {
return Collections.emptyList();
}
List<T> o = new ArrayList<>();
for(int i=0, l = array.length(); i < l; i++) {
o.add((T) array.get(i));
}
return o;
}
public static void test() {
List<Object> values = new ArrayList<>();
values.add("Product");
JSONObject jsonObject = new JSONObject();
jsonObject.put("key", values);
List<Long> test = new ArrayList<>();
test = toArray((JSONArray) jsonObject.get("key"));
System.out.println(test);
}
上面的代码允许将String
值存储在 a 中List<Long>
,这完全是荒谬的。任何帮助非常感谢?
解决方案
这一行:
o.add((T) array.get(i));
将生成未经检查的强制转换警告。
未经检查的强制转换是编译器无法插入checkcast
字节码指令来检查它是否真的是您要强制转换的类型的实例的强制转换。它不能在这里这样做,因为它不知道什么T
是“是”。
你只是在做一些不安全的事情。除非您取消了警告,否则您将收到警告(这不是一个好主意,因为您不会被告知要做不安全的事情)。
这就是 Java 的工作方式。
您可以通过传入 a Function<Object, T>
(或更一般地说,Function<Object, ? extends T>
)作为参数来安全地执行此操作:
public static <T> List<T> toArray(JSONArray array, Function<Object, ? extends T> checker) {
// ...
o.add(checker.apply(array.get(i)));
// ...
}
现在,确保它是 a 的责任T
被委托给checker
:您可以调用此方法,例如:
test = toArray((JSONArray) jsonObject.get("key"), Long.class::cast);
如果元素不是Long
.
推荐阅读
- sql - 从系统 MS SQL Server 获取列信息
- jquery - 使用 Jquery 嵌套表单字段
- mysql - MySQL SELECT 计算精度(小数点后的数字)
- assembly - 为什么 powerpc 需要这个额外的绒毛来使原始机器代码功能工作?
- c++ - 为什么我的地图迭代器中有语法错误?
- java - 无法从 sharedpreference 中读取字符串集(变量值消失)
- python - 使用 beautifulsoup4 抓取时数据丢失
- windows - Jenkinsfile windows cmd 输出变量参考
- javascript - firebase.auth 不是一个函数 - 具有多个 firebase 应用程序初始化
- python - Tkinter - 如何根据输入框用户输入设置变量