[英]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
Integer
是Object
的子类型,它是包含的所有类型的子类型? 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
的超类型,因此Integer
或String
不能是实际的类型参数。 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.