java - 如果在集合实例化期间未指定类型参数之一,会发生什么情况?

标签 java generics collections raw-types

Java中集合的实例化通常如下:

ArrayList<Integer> ali = new ArrayList<Integer>();

据说,按照这个约定,某些错误例如

String s = (String)ali(0)

可能导致编译错误而不是运行时异常。

但是,我观察到,虽然

ArrayList ali = new ArrayList<Integer>();

会导致上面的情况引起运行时异常,

ArrayList<Integer> ali = new ArrayList();

上述情况仍然会导致编译时错误。

是否有什么我错过的,或者如果我们不关心代码的清晰度,我们可以忽略右侧的类型吗?

谢谢!

最佳答案

ArrayList<Integer> ali = new ArrayList();

ArrayList ali = new ArrayList<Integer>();

这将生成一个编译器警告:未检查的转换。如果您不忽略这些警告,或者使用注释抑制它们,因为您可以证明它是安全的,那么您只能获得泛型的编译安全性。

您提出了一个有趣的观点:

ArrayList<Integer> ali = new ArrayList();

由于您只会使用 ali,因此您的引用确实安全。但是,您将在表达式的右侧收到编译器警告,因此最好添加参数化类型并使编译器免受警告。编译器警告您的原因是因为有人可能会这样做:

ArrayList<String> strings = new ArrayList<String>();
ArrayList<Integer> integers = new ArrayList(strings);

哦,不,你现在已经在整数中添加了字符串!

这就是 Java 7 类型推断的用武之地

ArrayList<Integer> ali = new ArrayList<>();

因此不再需要指定参数化类型,因为 Integer 是推断出来的。您可以在 Java 5 或 6 中通过编写一个泛型方法(例如 makeArrayList())来推断类型(请参阅 Joshua Bloch effective Java 书)

关于java - 如果在集合实例化期间未指定类型参数之一,会发生什么情况?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6279833/

相关文章:

java - 加类计算器

java - 在这个 Java 类层次结构中,如何使用泛型来避免类型转换?

Java this 和泛型?

java - 删除匿名监听器

java - 在应用程序启动时设置环境变量

java - 通过下载管理器下载后安装新的 apk 并退出正在运行的应用程序

java - 俄罗斯方 block 游戏 - 独立于计时器的快速左右移动

c# - List<T> 其中 T 是自定义对象。按属性删除重复项

java - 集合上的线程安全迭代

java - 是否有任何 Java 库提供随机访问队列实现?