简体   繁体   English

为什么是富 <String> 被视为Foo的子类型(扩展) <? extends Object> ?

[英]Why is Foo<String> considered a subtype (extended) of Foo<? extends Object>?

This is an extension of this SO answer . 这是此SO答案的扩展。

Note: This is not a duplicate of the following. 注意:这不是以下内容的重复项。 Why List is not a subtype of List<Number> but is subtype of List<? extends Number> 为什么List不是List<Number>的子类型,而是List<Number>子类型List<? extends Number> List<? extends Number> ? List<? extends Number> , nor any of the questions this has been marked duplicate of. ,也不会将此问题标记为重复的任何问题。 Let me explain. 让我解释。

The actual question was (edited to remove unnecessary code), 实际的问题是 (已编辑以删除不必要的代码),

void wildcardsMethod(List<? super Pair<? super Number>> list) {}

//... From some method.
    List<Pair<Object>> list = null;
    wildcardsMethod(list);
    // Error: wildcardsMethod(List<? super Pair<? super Number>>) is not applicable for the arguments (List<Pair<Object>>)

The above doesn't work . 以上无效

And the answer given was similar to (if I have not misunderstood), 给出的答案类似于 (如果我没有误解的话),

Pair<Object> is a subtype of Pair<? super Number> Pair<Object>Pair<? super Number>子类型 Pair<? super Number> Pair<? super Number> and so it cannot be used in place of <? super Pair<>> Pair<? super Number> ,因此不能代替<? super Pair<>> <? super Pair<>> . <? super Pair<>>

I don't understand it in this context. 在这种情况下,我不理解。 I was thinking it's just a Pair object and we should be able to use it in place of both <? extends Pair<>> 我以为这只是一个Pair对象,我们应该可以代替两个<? extends Pair<>> <? extends Pair<>> and <? super Pair<>> <? extends Pair<>><? super Pair<>> <? super Pair<>> . <? super Pair<>> But it doesn't work in the latter. 但这在后者中不起作用。

Can someone explain why it's considered to be a subtype thus limiting it to only extends and not super . 有人可以解释为什么将其视为子类型,从而将其限制为仅extends而不是super

EDIT: 编辑:

To explain a little more, let's see why we will the method (considering PECS ), 为了进一步说明,让我们看看为什么要使用该方法(考虑PECS ),

void wildcardsMethod(List<? super Pair<? super Number>> list) {}

You will be using it to add a Pair<Number> object to the passed list . 您将使用它来 Pair<Number>对象添加到传递的list

In this case, List<Pair<Object>> is a valid list which can accept a Pair<Number> object. 在这种情况下, List<Pair<Object>>是可以接受Pair<Number>对象的有效列表。

So, why is this not allowed? 那么,为什么不允许这样做?

You might be missing the forest for the trees, and think that List<Pair<Object>> is the same as List<? super Pair<? super Number>> 您可能缺少树木的森林,并认为List<Pair<Object>>List<? super Pair<? super Number>>相同List<? super Pair<? super Number>> List<? super Pair<? super Number>> List<? super Pair<? super Number>> , when they are not . List<? super Pair<? super Number>> ,如果不是

List<? super Pair<? super Object>> List<? super Pair<? super Object>> declares that a list will contain either Pair<Object> or a supertype of Pair<Object> , which could be Object or some other ancestral class between Object and Pair<T> . List<? super Pair<? super Object>>声明一个列表将包含任一Pair<Object>或的超类型 Pair<Object> ,它可以是Object或之间的某个其它祖先类ObjectPair<T> List<Pair<Object>> declares that only Pair objects or objects that can be considered a Pair will ever exist in that class. List<Pair<Object>>声明 Pair物体或可被视为一个对象Pair将在类曾经存在。

The bounds are going in different directions. 界限朝着不同的方向发展。 You're implicitly getting List<? extends Pair<? super Object>> 您隐式获得List<? extends Pair<? super Object>> List<? extends Pair<? super Object>> List<? extends Pair<? super Object>> with the first declaration. 带有第一个声明的List<? extends Pair<? super Object>>

The only way you could reasonably do this is if the list you were passing in were also bound in a similar fashion. 合理执行此操作的唯一方法是,如果传入的列表也以类似的方式绑定。 That is, you would want to be passing in a List<? super Pair<? super Number>> 也就是说,您希望传递一个List<? super Pair<? super Number>> List<? super Pair<? super Number>> List<? super Pair<? super Number>> . List<? super Pair<? super Number>>

When you say "A is a subtype of B", what that means by definition , is that every object of type A is also an object of type B. Now if you declare a variable with Foo<? extends Object> x; 当您说“ A是B的子类型”时, 根据定义 ,这意味着A类型的每个对象也是B类型的对象。现在,如果用Foo<? extends Object> x;声明一个变量Foo<? extends Object> x; Foo<? extends Object> x; , that means that the objects that x can refer to are precisely those objects which are of type Foo<something> (where something extends Object ). ,这意味着x可以引用的对象恰好是Foo<something>类型(其中something Object扩展了Object )的那些Object Obviously, that includes objects of type Foo<String> . 显然,这包括类型为Foo<String>对象。

So every Foo<String> is also a Foo<? extends Object> 那么每个Foo<String>也是Foo<? extends Object> Foo<? extends Object> - so by definition, Foo<String> is a subtype of Foo<? extends Object> Foo<? extends Object> -因此根据定义, Foo<String>Foo<? extends Object>的子类型Foo<? extends Object> Foo<? extends Object> . Foo<? extends Object>

Likewise, every Pair<Object> is also a Pair<? super Number> 同样,每个Pair<Object>也是Pair<? super Number> Pair<? super Number> - so by definition, Pair<Object> is a subtype of Pair<? super Number> Pair<? super Number> -因此根据定义, Pair<Object>Pair<? super Number>的子类型Pair<? super Number> Pair<? super Number> . Pair<? super Number>

After thinking about Makoto's answer for sometime I understood what it meant. 在思考了Makoto的答案一段时间后,我明白了它的含义。

Note: I am writing this answer in a format which I can easily understand for future reference (though his will be the accepted answer) 注意:我以易于理解的格式编写此答案,以备将来参考(尽管他将被接受)

Let's say we have the method in question defined like this (considering PECS), 假设我们有这样定义的方法(考虑PECS),

void wildcardsMethod(List<? super Pair<? super Number>> list) {
    Pair<Number> pairOfNumbers = new Pair<Number>();
    list.add(pairOfNumbers);
}

and we are calling the method with this argument ( assuming it was allowed ), 并且我们使用此参数调用该方法( 假设已允许 ),

List<Pair<Object>> listOfPairOfObjects = new ArrayList<Pair<Object>>();
wildcardsMethod(listOfPairOfObject);

Now, a Pair<Number> object is added to listOfPairOfObjects . 现在,将Pair<Number>对象添加到listOfPairOfObjects

Also remember that the rules of PECS only apply to the list reference in wildcardsMethod and not the listOfPairOfObjects reference. 还要记住, PECS的规则仅适用wildcardsMethodlist引用,而不适用于listOfPairOfObjects引用。

Hence I can do, 因此我可以

Pair<Object> pairOfObjects = listOfPairOfObjects.get(0);

Now, since a Pair<Number> was added to the list in the method, I will receive a Pair<Number> object when I expect a Pair<Object> reference . 现在,由于将Pair<Number>添加到该方法的列表中,因此当我希望使用Pair<Object>引用时我将收到Pair<Number>对象

And these both are totally incompatible types. 这些都是完全不兼容的类型。 Hence the error. 因此,错误。

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

相关问题 为什么列出 <? extends Foo> 不接受Foo类的对象? - Why does the List<? extends Foo> not accept an object of the Foo class? 实例化使用 <Foo extends Bar<Foo> &gt; - Instantiating a generic object that uses <Foo extends Bar<Foo>> 填写清单<? extends Foo> - Filling a List<? extends Foo> 为什么在Java中不允许Foo(Object [])重载Foo(Object…)? - Why is it not allowed in Java to overload Foo(Object…) with Foo(Object[])? 如何投射List <? extends Foo> 列表 <Foo> - How to cast List<? extends Foo> to List<Foo> 是否可以做“上课” <? extends foo> foo”? - Is it possible to do “Class<? extends foo> foo”? 为什么foo(1,2,3)没有作为整数[]传递给varargs方法foo(Object ...) - Why is foo(1,2,3) not passed to varargs method foo(Object… ) as an Integer[] 在Java中,为什么调用foo()没有给定2个varags方法foo(int ... ints)和foo(Object ... objects)? - In Java, why is the call foo() not ambigious given 2 varags methods foo(int… ints) and foo(Object… objects)? Java泛型:Foo<T> , Foo, Foobar <T extends Foo<T> &gt; 和 Foobar<T extends Foo> - Java Generics: Foo<T>, Foo, Foobar<T extends Foo<T>> and Foobar<T extends Foo> Dagger 2:如何注入Map <Class <?扩展Foo>,Provider <?延伸Foo >> - Dagger 2: How to inject Map<Class<? extends Foo>, Provider<? extends Foo>>
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM