为什么可以插入String到List<Integer>在下面的代码?我有一个类将数字插入到整数列表中:
public class Main {
public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer>();
list.add(2);
list.add(3);
list.add(4);
Inserter inserter = new Inserter();
inserter.insertValue(list);
System.out.print(list);
}
}
Run Code Online (Sandbox Code Playgroud)
然后,我有一个单独的类,其插入String到一个List,与所述数字串值"42":
public class Inserter {
void insertValue(List list)
{
list.add(new String("42"));
}
}
Run Code Online (Sandbox Code Playgroud)
为什么编译器不会引发编译器错误,或者运行时抛出运行时异常,例如*CastException,当我添加String到整数列表时?另外,为什么System.out.print(list)产生如下的输出而不抛出任何异常?
[2, 3, 4, 42]
Run Code Online (Sandbox Code Playgroud)
允许所有这些发生的根本原因是什么?
这可能是一个例子来说明泛型的类型擦除(我建议阅读该链接以完全理解它以及它在Java泛型中扮演的关键角色).
list 被宣布为 List<Integer>listValue它时,它被转换为原始类型Object †print命令只调用toString列表,它不介意它包含的内容,因此它打印包含字符串的元素.如果要查看异常,请尝试添加一行:
Integer myInt = list.get(3); // try to get the string
Run Code Online (Sandbox Code Playgroud)
这将抛出一个ClassCastException编译器,在擦除期间,在必要时插入强制转换以保护类型安全.
†参数化类型的转换,例如List<Integer>原始类型,例如List,给你一个编译器警告,告诉你这种问题可能即将发生.您可以使用@SuppressWarnings("unchecked")(或者"rawtypes",如果它可用)来抑制该警告.这是一种"承认"你将要做一些会导致未经检查的运行时异常的好方法,并且还有助于告诉其他未来的编码人员可能会发生一些时髦的事情.例如:
void insertValue(@SuppressWarnings("unchecked") List list)
{
list.add(new String("42"));
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1316 次 |
| 最近记录: |