java <E extends Number> 和 <Number> 有什么区别?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2770264/
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
What is the difference between <E extends Number> and <Number>?
提问by unj2
What is the difference between this method declaration:
这个方法声明有什么区别:
public static <E extends Number> List<E> process(List<E> nums){
and
和
public static List<Number> process(List<Number> nums){
Where would you use the former?
你会在哪里使用前者?
回答by polygenelubricants
The first allows processof a List<Integer>, a List<Double>, etc. The second doesn't.
第一个允许processa List<Integer>、 aList<Double>等。第二个不允许。
Generics in Java are invariant. They're not covariant like arrays.
Java 中的泛型是不变的。它们不像数组那样是协变的。
That is, in Java, Double[]is a subtype of Number[], but a List<Double>is NOT a subtype of List<Number>. A List<Double>, however, is a List<? extends Number>.
也就是说,在 Java 中,Double[]是 的子类型Number[],但 aList<Double>不是 的子类型List<Number>。List<Double>然而,A是一个List<? extends Number>。
There are good reasons for generics being invariant, but that's also why the extendsand supertype are often necessary for subtyping flexibility.
泛型不变是有充分理由的,但这也是为什么extends和super类型对于子类型灵活性通常是必需的。
See also
也可以看看
- Java Tutorials/Generics/Subtyping
- Explains why generics invariance is a good thing
- More fun with wildcards
- Explains some uses of
superandextendsfor bounded wildcards
- Explains some uses of
- Java Generics: What is PECS?
- This discusses the "Producer
extendsConsumersuper" principle - Effective Java 2nd Edition, Item 28: Use bounded wildcards to increase API flexibility
- This discusses the "Producer
- Java 教程/泛型/子类型
- 解释为什么泛型不变性是一件好事
- 通配符带来更多乐趣
- 解释有界通配符的一些用途
super和用途extends
- 解释有界通配符的一些用途
- Java泛型:什么是PECS?
- 这讨论了“生产者
extends消费者super”原则 - Effective Java 2nd Edition,Item 28:使用有界通配符来增加 API 的灵活性
- 这讨论了“生产者
回答by Bert F
The latter method(the one without<E extends Number>) will only accept a parameter of exactly type List<Number>and will it always
return a List<Number>. For example, it will notaccept List<Integer>.
在后一种方法(所述一个无<E extends Number>)将只接受的准确类型的参数List<Number>,并且将它总是返回List<Number>。例如,它不会接受List<Integer>.
The former method(the one with<E extends Number>) is a generic method, meaning it can accept different types of Lists
and it will return the same type of List, as long as the Lists are lists of somethingthat
extends Number, e.g. List<Integer>.
在前者的方法(将一个用<E extends Number>)是一种通用的方法,这意味着它可以接受不同类型的ListS和它将返回同一类型的List,只要Lists为名单东西延伸Number,例如List<Integer>。
Example:
例子:
import java.util.ArrayList;
import java.util.List;
public class ProcessGenerics {
List<Number> listNumber = new ArrayList<Number>();
List<Integer> listInteger = new ArrayList<Integer>();
List<Double> listDouble = new ArrayList<Double>();
public static
List<Number> processWithoutExtends(List<Number> nums){ return nums; }
List<Number> resultN = processWithoutExtends(listNumber); // OK
//List<Integer> resultI = processWithoutExtends(listInteger); // compile-error - method not applicable
//List<Double> resultD = processWithoutExtends(listDouble); // compile-error - method not applicable
public static <E extends Number>
List<E> processWithExtends(List<E> nums){ return nums; }
List<Number> resultN2 = processWithExtends(listNumber); // OK
List<Integer> resultI2 = processWithExtends(listInteger); // OK
List<Double> resultD2 = processWithExtends(listDouble); // OK
}
See a similar explanation in the Wildcards chapter in the Generics Lesson in the Java Tutorials:
http://java.sun.com/docs/books/tutorial/java/generics/subtyping.html
在 Java 教程中的泛型课程的通配符一章中看到类似的解释:http:
//java.sun.com/docs/books/tutorial/java/generics/subtyping.html
See also How to cast a list of inheriting objects to a collection of objects in Java?Both questions are really about generics and subtypes, e.g. whether List<Integer>is a subtype of List<Number>(it's not!!!).
另请参阅如何将继承对象列表转换为 Java 中的对象集合?这两个问题实际上都与泛型和子类型有关,例如是否List<Integer>是List<Number>(不是!!!)的子类型。

