gridlayout - foreach java list
¿Cuál es la diferencia entre<E se extiende Número> y<Número>? (2)
El último método (el que no tiene <E extends Number>
) solo aceptará un parámetro de tipo exactamente List<Number>
y siempre devolverá un List<Number>
. Por ejemplo, no aceptará List<Integer>
.
El primer método (el que tiene <E extends Number>
) es un método genérico , lo que significa que puede aceptar diferentes tipos de List
s y devolverá el mismo tipo de List
, siempre que las List
s sean listas de algo que se extienda Number
, por ejemplo, List<Integer>
.
Ejemplo:
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
}
Consulte una explicación similar en el capítulo de Comodines en la Lección de genéricos en los Tutoriales de Java:
http://java.sun.com/docs/books/tutorial/java/generics/subtyping.html
Consulte también ¿Cómo lanzar una lista de objetos heredados a una colección de objetos en Java? Ambas preguntas son realmente sobre genéricos y subtipos, por ejemplo, si List<Integer>
es un subtipo de List<Number>
(¡no lo es!).
Cuál es la diferencia entre esta declaración de método:
public static <E extends Number> List<E> process(List<E> nums){
y
public static List<Number> process(List<Number> nums){
¿Dónde usarías el primero?
El primero permite el process
de una List<Integer>
, una List<Double>
, etc. El segundo no.
Los genéricos en Java son invariables. No son covariantes como matrices.
Es decir, en Java, Double[]
es un subtipo de Number[]
, pero una List<Double>
NO es un subtipo de List<Number>
. Una List<Double>
, sin embargo, es una List<? extends Number>
List<? extends Number>
.
Hay buenas razones para que los genéricos sean invariables, pero también es por eso que el tipo de extends
y super
suele ser necesario para la flexibilidad de subtipado.
Ver también
- Tutoriales de Java / Generics / Subtyping
- Explica por qué la invarianza de los genéricos es algo bueno
- Más diversión con comodines
- Explica algunos usos de
super
yextends
para comodines delimitados
- Explica algunos usos de
- Genéricos de Java: ¿Qué es PECS?
- Esto discute el principio "Productor
extends
consumidorsuper
" - Effective Java 2nd Edition , Item 28: Use comodines delimitados para aumentar la flexibilidad de la API
- Esto discute el principio "Productor