Object类真的可以下限吗?

时间:2012-08-10 18:03:58

标签: java generics

为什么String&amp ;;整数不是Object的超类?

List<? super Object> mylist = new ArrayList<Object>();
mylist.add("Java"); // no compile error
mylist.add(2);

我知道wild card guidelines使用较低的有界外卡和超出'out'变量,但在这种情况下,似乎Object不起'下界'的作用。

这也是允许在列表中添加任何类型的唯一方法吗?

3 个答案:

答案 0 :(得分:4)

这很简单。请记住,在Java中,子类型的实例也是其超类型的实例。

查看add

的签名
public boolean add(E e)

这意味着无论您传递的是类型为E的内容还是E的任何子类型。

你有List<? super Object>。因此,您可以传递myList.add()类型为? super Object(可能是Object或其超类型的未知类型)或其任何子类型的任何内容。

整数是? super Object包含的所有类型的子类型吗?当然。 IntegerObject的子类型,它是? super Object包含的所有类型的子类型(当然,在这种情况下,只有Object满足此要求。)

您将type参数与可以传递给方法的内容混淆。 List<? super Object>类型参数是未知类型,是Object的超类型,因此IntegerString不能是实际的类型参数。实际上,在这种情况下,唯一有效的实际类型参数是Object。但是当你传递一些东西给你的方法时,你问的是,我正在传递一个子类型吗?答案是肯定的。

答案 1 :(得分:3)

这是因为Object是Integer和String的超类。你正在以相反的方式解释泛型关系。

修改

想想这种情况:

List<? extends myClass> listOfMyClass = new ArrayList<Object>();

在这种情况下,您最终会得到Object类型元素的列表,但必须遵守listOfMyClass列表声明所添加的限制。

您将能够将属于myClass层次结构的任何对象添加到列表中。实现ArrayList接口的List将在请求时保留(并返回)Object个类型元素。

当然,您可以定义:

List<? extends myClass> listOfMyClass = new ArrayList<mySuperClass>(); 

正如您现在所做的那样,ArrayList必须包含具有相同类型或超类型myClass的对象,在这种情况下,这是mySuperClass。此列表将返回qhen请求的mySuperClass个对象。

ClassX作为不属于mySuperClass层次结构的类,以下行将无法编译:

List<? extends myClass> listOfMyClass = new ArrayList<ClassX>(); 

那是因为ClassX不是myClass的超类。

答案 2 :(得分:3)

我同意这令人困惑,但这就是正在发生的事情。

在这行代码中:

List<? super Object> mylist...

您说myListList,其中每个元素的类型可以是Object,也可以是超级类Object。但是,您只是在这里声明myList的类型。

通配符的作用限制了myList的实现。

然后,你这样做:

List<? super Object> mylist = new ArrayList<Object>();

现在您正在做的是实例化ArrayList<Object>。您的下限通配符用于检查这是否有效。它有效,因为Object匹配? super Object。此时,您有一个List<Object>,并允许您随后的方法调用。