Java 通用列表<列表<? 扩展数>>
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/746089/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java Generic List<List<? extends Number>>
提问by
How come in java we cannot do:
为什么在java中我们不能这样做:
List<List<? extends Number>> aList = new ArrayList<List<Number>>();
Even though this is OK:
即使这没问题:
List<? extends Number> aList = new ArrayList<Number>();
Compiler error message is:
编译器错误信息是:
Type mismatch: cannot convert from ArrayList<List<Number>> to List<List<? extends Number>>
Type mismatch: cannot convert from ArrayList<List<Number>> to List<List<? extends Number>>
回答by eulerfx
I'm not very familiar with Java syntax but it seems that your issue is this:
我对 Java 语法不是很熟悉,但您的问题似乎是这样的:
回答by Apocalisp
Your statement does not compile because List<? extends Number>is not the same type as List<Number>. The former is a supertype of the latter.
您的语句无法编译,因为List<? extends Number>与List<Number>. 前者是后者的超类型。
Have you tried this? Here I'm expressing that the List is covariant in its type argument, so it will accept any subtype of List<? extends Number>(which includes List<Number>).
你试过这个吗?在这里,我表示 List 在其类型参数中是协变的,因此它将接受List<? extends Number>(包括List<Number>) 的任何子类型。
List<? extends List<? extends Number>> aList = new ArrayList<List<Number>>();
Or even this. Here the type parameter for the ArrayList on the right-hand side is the same as the type parameter on the left-hand side, so variance is not an issue.
甚至这个。这里右侧 ArrayList 的类型参数与左侧的类型参数相同,因此差异不是问题。
List<List<? extends Number>> aList = new ArrayList<List<? extends Number>>();
You should be able to just say
你应该可以说
List<List<Number>> aList = new ArrayList<List<Number>>();
I tend to avoid the ?type wildcard whenever possible. I find that the expense incurred in type annotation is not worth the benefit.
我倾向于尽可能避免使用?类型通配符。我发现类型注释中产生的费用不值得收益。
回答by Steve Reed
You should definitely use the ? type wildcard when appropriate, do not avoid it as a general rule. For example:
你绝对应该使用 ? 在适当的时候输入通配符,一般情况下不要避免使用通配符。例如:
public void doThingWithList(List<List<? extends Number>> list);
allows you to pass a List<Integer>or a List<Long>.
允许您传递 aList<Integer>或List<Long>.
public void doThingWithList(List<List<Number>> list);
allows you to only pass arguments declared as List<Number>. A small distinction, yes, but using the wildcard is powerful and safe. Contrary to how it may seem, a List<Integer>is not a subclass, or is not assignable, from List<Number>. Nor is List<Integer>a subclass of List<? extends Number, which is why the code above does not compile.
允许您只传递声明为List<Number>. 一个小小的区别,是的,但使用通配符是强大且安全的。与它看起来的相反, aList<Integer>不是子类,或者不可分配,来自List<Number>。也不是List<Integer>的子类List<? extends Number,这就是上面的代码无法编译的原因。
回答by John Feminella
In Java, if Caris a derived class of Vehicle, then we can treat all Carsas Vehicles; a Caris a Vehicle. However, a Listof Carsis not also a Listof Vehicles. We say that List<Car>is not covariantwith List<Vehicle>.
在 Java 中,如果Car是 的派生类Vehicle,那么我们可以将所有Cars视为Vehicles; 一个Car是一个Vehicle。然而,a ListofCars也不是 a Listof Vehicles。我们说List<Car>的不是协变有List<Vehicle>。
Java requires you to explicitly tell it when you would like to use covariance and contravariance with wildcards, represented by the ?token. Take a look at where your problem happens:
Java 要求您明确告诉它何时想要使用通配符表示的协方差和逆变?。看看你的问题发生在哪里:
List<List<? extends Number>> l = new ArrayList<List<Number>>();
// ---------------- ------
//
// "? extends Number" matched by "Number". Success!
The inner List<? extends Number>works because Numberdoes indeed extend Number, so it matches "? extends Number". So far, so good. What's next?
内部List<? extends Number>工作因为Number确实扩展Number,所以它匹配“ ? extends Number”。到现在为止还挺好。下一步是什么?
List<List<? extends Number>> l = new ArrayList<List<Number>>();
// ---------------------- ------------
//
// "List<? extends Number>" not matched by "List<Number>". These are
// different types and covariance is not specified with a wildcard.
// Failure.
However, the combined inner type parameter List<? extends Number>is not matched by List<Number>; the types must be exactly identical. Another wildcard will tell Java that this combined type should also be covariant:
但是,组合的内部类型参数List<? extends Number>不匹配List<Number>; 类型必须完全相同。另一个通配符将告诉 Java 这种组合类型也应该是协变的:
List<? extends List<? extends Number>> l = new ArrayList<List<Number>>();
回答by Alex
List<List<? extends Number>> aList = new ArrayList<List<? extends Number>>();
aList.add(new ArrayList<Integer>());

