Depende de lo que necesites hacer. Debe utilizar el parámetro de tipo acotado si desea hacer algo como esto:
public <T extends Shape> void addIfPretty(List<T> shapes, T shape) {
if (shape.isPretty()) {
shapes.add(shape);
}
}
Aquí tenemos un List<T> shapes
y un T shape
, por lo tanto, podemos hacerlo con seguridad shapes.add(shape)
. Si fue declarado List<? extends Shape>
, NO puede add
hacerlo con seguridad (porque puede tener un List<Square>
y un Circle
).
Entonces, al darle un nombre a un parámetro de tipo acotado, tenemos la opción de usarlo en otro lugar de nuestro método genérico. Esta información no siempre es necesaria, por supuesto, por lo que si no necesita saber mucho sobre el tipo (por ejemplo, su drawAll
), entonces basta con utilizar comodines.
Incluso si no se está refiriendo al parámetro de tipo delimitado nuevamente, se requiere un parámetro de tipo delimitado si tiene varios límites. Aquí hay una cita de las preguntas frecuentes sobre genéricos de Java de Angelika Langer
¿Cuál es la diferencia entre un enlace comodín y un enlace de parámetro de tipo?
Un comodín solo puede tener un límite, mientras que un parámetro de tipo puede tener varios límites. Un comodín puede tener un límite inferior o superior, mientras que no existe un límite inferior para un parámetro de tipo.
Los límites comodín y los límites de los parámetros de tipo a menudo se confunden, porque ambos se denominan límites y tienen en parte una sintaxis similar. […]
Sintaxis :
type parameter bound T extends Class & Interface1 & … & InterfaceN
wildcard bound
upper bound ? extends SuperType
lower bound ? super SubType
Un comodín solo puede tener un límite, ya sea un límite inferior o superior. No se permite una lista de límites comodín.
Un parámetro de tipo, en contraposición, puede tener varios límites, pero no existe un límite inferior para un parámetro de tipo.
Citas de Effective Java 2nd Edition, artículo 28: Utilice comodines delimitados para aumentar la flexibilidad de la API :
Para una máxima flexibilidad, utilice tipos de comodines en los parámetros de entrada que representan a los productores o consumidores. […] PECS significa productor extends
, consumidor, super
[…]
No utilice tipos de comodines como tipos de devolución . En lugar de proporcionar flexibilidad adicional a sus usuarios, los obligaría a utilizar tipos de comodines en el código del cliente. Si se utilizan correctamente, los tipos de comodines son casi invisibles para los usuarios de una clase. Hacen que los métodos acepten los parámetros que deberían aceptar y rechacen los que deberían rechazar. Si el usuario de la clase tiene que pensar en tipos de comodines, probablemente haya algo mal con la API de la clase .
Aplicando el principio PECS, ahora podemos volver a nuestro addIfPretty
ejemplo y hacerlo más flexible escribiendo lo siguiente:
public <T extends Shape> void addIfPretty(List<? super T> list, T shape) { … }
Ahora podemos addIfPretty
, decir, a Circle
, a a List<Object>
. Obviamente, esto es seguro para los tipos y, sin embargo, nuestra declaración original no era lo suficientemente flexible como para permitirlo.
Preguntas relacionadas
Resumen
- Utilice parámetros / comodines de tipo acotado, aumentan la flexibilidad de su API
- Si el tipo requiere varios parámetros, no tiene más remedio que utilizar el parámetro de tipo acotado
- si el tipo requiere un límite inferior, no tiene más remedio que utilizar un comodín acotado
- Los "productores" tienen límites superiores, los "consumidores" tienen límites inferiores
- No utilice comodines en tipos de devolución