简体   繁体   English

Object类真的可以下限吗?

[英]Can the Object class really be a lower bound?

Why is the following legal when String & Integer are not super classes of Object ? 当String&Integer不是Object的超类时,为什么以下是合法的?

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

I'm aware that wild card guidelines use lower bounded wild cards and super for 'out' variables but it seems that Object doesn't function as a 'lower bound' in this case. 我知道外卡指南使用较低的有界外卡和超出'出'变量,但在这种情况下,似乎对象不起'下界'的作用。

Also is this the only way to allow addition of any type into a list ? 这也是允许在列表中添加任何类型的唯一方法吗?

It's really simple. 这很简单。 Remember that in Java, an instance of a subtype is also an instance of its supertypes. 请记住,在Java中,子类型的实例也是其超类型的实例。

Look at the signature of add 看看add的签名

public boolean add(E e)

That means whatever you pass something whose type is E or any subtype of E . 这意味着,无论你通过什么类型为E或任何亚型E

You have a List<? super Object> 你有一个List<? super Object> List<? super Object> . List<? super Object> So you can pass to myList.add() anything whose type is ? super Object 所以你可以传递给myList.add()任何类型的东西? super Object ? super Object (an unknown type which could be Object or supertype thereof) or any subtype thereof. ? super Object (可以是Object或其超类型的未知类型)或其任何子类型。

Is Integer a subtype of all types contained by ? super Object 整数是包含的所有类型的子类型? super Object ? super Object ? ? super Object Of course. 当然。 Integer is a subtype of Object , which is a subtype of all types contained by ? super Object IntegerObject的子类型,它是包含的所有类型的子类型? super Object ? super Object (of course, in this case, only Object satisfies this). ? super Object (当然,在这种情况下,只有Object满足这一点)。

You're confusing the type parameter with the things you can pass to methods. 您将type参数与可以传递给方法的内容混淆。 The type argument of List<? super Object> List<? super Object>类型参数 List<? super Object> is an unknown type that is a supertype of Object , so Integer or String cannot be the actual type parameter. List<? super Object>是一个未知类型,它是Object的超类型,因此IntegerString不能是实际的类型参数。 In fact, in this case the only valid actual type argument would be Object . 实际上,在这种情况下,唯一有效的实际类型参数是Object But what you're asking when you pass something to the method is, is the thing I'm passing a subtype? 但是当你传递一些东西给你的方法时,你问的是,我正在传递一个子类型吗? And the answer is yes. 答案是肯定的。

It's because Object is a superclass for Integer and String. 这是因为Object是Integer和String的超类。 You're interpreting the generic relationship the other way around. 你正在以相反的方式解释泛型关系。

Edit 编辑

Think about this situation: 想想这种情况:

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

In this case, you'll end up with a list of Object type elements but that have to respect the restriction added by the declaration of the listOfMyClass list. 在这种情况下,您最终会得到一个Object类型元素列表,但必须遵守listOfMyClass列表声明所添加的限制。

You'll be able to add any object that belongs to the myClass hierarchy to the list. 您将能够将属于myClass层次结构的任何对象添加到列表中。 The ArrayList that's implementing the List interface will hold (and return) Object type elements when requested. 实现List接口的ArrayList将在请求时保存(并返回) Object类型元素。

Of course, you can define this: 当然,您可以定义:

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

As you might now, the ArrayList must contain objects with the same type or a supertype of myClass and, in this case, that's the mySuperClass . 就像你现在一样, ArrayList必须包含具有相同类型的对象或myClass的超类型,在这种情况下,它是mySuperClass This list will return mySuperClass objects qhen requested. 此列表将返回qhen请求的mySuperClass对象。

Taking ClassX as a class that does not belong to the mySuperClass hierarchy, the following line won't compile: ClassX作为不属于mySuperClass层次结构的类,以下行将无法编译:

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

That's because ClassX is not a superclass of myClass . 那是因为ClassX不是myClass的超类。

I agree that it's confusing, but here's what's happening. 我同意这令人困惑,但这就是正在发生的事情。

In this line of code: 在这行代码中:

List<? super Object> mylist...

You're saying that myList is a List , where each element can be of a type that is Object or a superclass of Object . 你是说myList是一个List ,其中每个元素可以是一个类型,它的Object或超类Object However, you're only declaring the type of myList here. 但是,您只是在这里声明myList的类型。

What the wildcard does is restricts your implementation of myList . 通配符的作用是限制myList的实现。

Then, you do this: 然后,你这样做:

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

Now what you're doing is instantiating an ArrayList<Object> . 现在你正在做的是实例化一个ArrayList<Object> Your lower bound wildcard is used to check that this is valid. 您的下限通配符用于检查这是否有效。 It is valid, because Object matches ? super Object 它是有效的,因为Object匹配? super Object ? super Object . ? super Object At this point, you have a List<Object> and your ensuing method calls are permitted. 此时,您有一个List<Object>并允许您随后的方法调用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM