对于带有泛型的类型安全来说非常重要

时间:2010-12-16 14:30:25

标签: java generics collections

有些奇怪的事我无法理解。泛型通常是一件好事。它在编译时提供类型安全性。例如:

class A{}

class B{}

static void someMethod() {
    List<B> listB = new ArrayList<B>();
    listB.add(B);
    listB.add(A); // here goes a compiler error

    // but this will compile fine
    List<Object> objList = new ArrayList<Object>();
    objList.add("String");
    objList.add(new Integer(9));
    objList.add(B);
}

那么,Java开发人员错过了什么?

6 个答案:

答案 0 :(得分:12)

Object是所有内容的基类,您要添加Object类型的对象。因此类型安全(因为所有插入的对象都满足对象类型的要求)。

答案 1 :(得分:9)

如果您创建Objects列表,则允许添加对象。这就是为什么你可以添加StringIntegerB的实例...... 它们都是对象!

也许您想知道为什么不允许 添加Objects。嗯,允许添加子类型非常方便。例如,考虑您要在列表中存储大量数字。你不知道它们是浮点数还是整数等等。然后你可以做

List<Number> numList = new ArrayList<Number>();
numList.add(new Double(5.5));
numList.add(new Integer(5));
numList.add(new Long(10L));

答案 2 :(得分:3)

简单来说,"String" new Integer(9)BObject,而B不是A

在继承中,如果 A扩展了B,然后是A is said to be of type一个and B as well; 对象is the超级班级。

答案 3 :(得分:2)

本质:

List l = new ArrayList();

被解释为

List<Object> l = new ArrayList<Object>();

所以,事实上,将任意对象添加到此列表中就可以了。这应该在编译时发出警告,因为您使用的是没有参数的参数化类型。

这是以这种方式实现的,以保持向后兼容性。如果使用new ArrayList()(或任何其他集合框架类)的所有非参数化代码突然无法编译,则需要花费大量时间和金钱来修复。是的,这意味着您可以编写不安全的代码,但是您会得到警告,至少您现有的1000万行应用程序仍然有效。

答案 4 :(得分:0)

Java泛型确实提供了正确的类型安全性,但您没有适当地指定边界。以下是泛型实际为您提供的示例:

List<Number> list1 = new ArrayList<Number>();
list1.add(new Integer(1)); // can add anything that is a Number
list1.add(new Double(1.0));
Number n = list1.get(0); // and retrieve Numbers

List<? super Number> list2 =  new ArrayList<Number>(); // can be a list of number
list2 = new ArrayList<Object>(); // or a list of objects
list2.add(new Integer(1)); // but can only add numbers
list2.add(new Double(1.0));
Object o1 = list2.get(0); // and only retrieve Objects

List<? extends Number> list3 = new ArrayList<Number>(); // can be a list of numbers
list3 = new ArrayList<Integer>(); // or any subtype of Number
list3 = new ArrayList<Double>();
list3.add(null); // but can add any thing to it
Number n2 = list3.get(0); // and only retrieve Numbers

答案 5 :(得分:0)

您的第一个示例失败的原因是A is not a B`。

第二个示例有效的原因是因为Stringnew Integer(9)B都是Object s。

这具有良好的逻辑意义,并且其他海报所说的原因也很实用。