问题1 - 为什么不将arrList1仅限于String?
ArrayList arrList1 = new ArrayList<String>();
arrList1.add(10);
arrList1.add("Manish");
arrList1.add(0.234);
问题2 - 没有编译错误但是给出了运行类型错误的原因?
ArrayList<String> arrList2 = new ArrayList<String>();
arrList2 = arrList1;
问题3 - 下面有什么用?
ArrayList<Integer> arrList3 = new ArrayList<Integer>();
arrList2 = arrList3; //compiler error that's fine
问题4 - 如何对arrList4进行操作?
ArrayList<?> arrList4 = new ArrayList<String>();
//arrList4.add("String"); //compilation error?
arrList4 = new ArrayList<Integer>();
arrList4.add(23); //compilation error?
问题5 - 在分配对象时使用泛型是什么,因为它不起作用?就像在arrList1?
ArrayList<String> arrList5 = new ArrayList();
arrList5.add("String");
arrList5.add(23.3); //compilation error that's fine
答案 0 :(得分:5)
Q1)泛型是编译时检查。您隐式将ArrayList强制转换为原始类型,因此编译器不知道您是如何创建它的。为什么允许这样做?为了向后兼容。它必须使用没有泛型的代码。例如Java 1.4.2
Q2)你得到运行时错误,因为它们与预期的类型不匹配,所以元素不是String。
Q3)外卡是未知类型。这并不意味着它匹配任何东西。如果你有一个? extends T
并且你得到这就知道这是一个T.在许多方面?使其只读,并且仅对返回值有用。
Q4)你把它变成了一个Integer的ArrayList,所以你必须添加一个Integer或int,它可以装箱到Integer。
Q5)有编译时和运行时检查。几乎在所有情况下都有一种绕过编译时间检查的方法(有些更模糊其他情况)。在第一个示例中,您已关闭编译器为您检查代码的能力,因此您在运行时会看到错误。就像你对编译器说的那样,相信我,我知道我在做什么。
尽管您可以使用@SuppressWarnings("checked")