Cómo implementar el método suma con un argumento de tipo comodín en su parámetro

Recuerde que el propósito del método 

suma

 en la fi gura 18.14 era obtener el total de cualquier tipo de objetos 

Number

 almacenados en un objeto 

ArrayList

. Creamos un objeto 

ArrayList

 de objetos 

Number

 que contenía 

objetos

Integer

 y 

Double

. Los resultados de la fi gura 18.14 demuestran que el método 

sumar

 trabajó correc-

tamente. Dado que el método 

sumar

 puede obtener el total de los elementos de un objeto 

ArrayList

 de objetos 

Number

, podríamos esperar que el método también funcionara para objetos 

ArrayList

 que contengan elemen-

tos de sólo un tipo numérico, como 

ArrayList< Integer >

. Así, modifi camos la clase 

TotalNumeros

 para crear 

un objeto 

ArrayList

 de objetos 

Integer

 y pasarlo al método 

sumar

. Al compilar el programa, el compilador 

genera el siguiente mensaje de error:

sumar(java.util.ArrayList<java.lang.Number>) in TotalNumerosErrores 
cannot be applied to (java.util.ArrayList<java.lang.Integer>)

Aunque 

Number

 es la superclase de 

Integer

, el compilador no considera que el tipo parametrizado 

ArrayList

< Number >

 sea un supertipo de 

ArrayList< Integer >

. Si lo fuera, entonces toda operación que pudiéramos 

realizar en 

ArrayList< Number >

 funcionaría también en un 

ArrayList< Integer >

. Considere el hecho de 

que puede sumar un objeto 

Double

 a un 

ArrayList< Number >

, debido a que un 

Double

es un 

Number

, pero no 

se puede sumar un objeto 

Double

 a un 

ArrayList< Integer >

, ya que un 

Double

no es un

Integer

. Por ende, 

no es válida la relación de los subtipos.

¿Cómo creamos una versión más fl exible del método 

sumar

 que pueda obtener el total de los elementos de 

cualquier objeto 

ArrayList

 que contenga elementos de cualquier subclase de 

Number

? Aquí es donde son impor-

tantes los 

argumentos tipo comodín

. Los comodines nos permiten especifi car parámetros de métodos, valores 

de retorno, variables o campos, etc., que actúan como supertipos de los tipos parametrizados. En la fi gura 18.15, 
el parámetro del método 

suma

 se declara en la línea 50 con el tipo:

ArrayList< ? 

extends

 Number >

Un argumento tipo comodín se denota mediante un signo de interrogación (

?

), que por sí solo representa un 

“tipo desconocido”. En este caso, el comodín extiende a la clase 

Number

, lo cual signifi ca que el comodín tiene 

un límite superior de 

Number

. Por ende, el argumento de tipo desconocido debe ser 

Number

 o una subclase de 

Number

. Con el tipo del parámetro que se muestra aquí, el método 

sumar

 puede recibir un argumento 

ArrayList

que contenga cualquier tipo de 

Number

, como 

ArrayList< Integer >

 (línea 20), 

ArrayList< Double >

 (línea 

33) o 

ArrayList< Number >

 (línea 46).

En las líneas 11 a 20 se crea e inicializa un objeto 

ArrayList< Integer >

 llamado 

listaEnteros

, se 

imprimen en pantalla sus elementos y se obtiene el total de los mismos mediante una llamada al método 

sumar

(línea 20). En las líneas 24 a 33 se realizan las mismas operaciones para un objeto 

ArrayList< Double >

 llamado 

listaDouble

. En las líneas 37 a 46 se realizan las mismas operaciones para un objeto 

ArrayList< Number >

llamado

listaNumeros

, el cual contiene objetos 

Integer

y

Double

.

En el método 

sumar

 (líneas 50 a 59), aunque los tipos de los elementos del argumento 

ArrayList

 no son 

directamente conocidos para el método, se sabe que por lo menos son de tipo 

Number

, ya que el comodín se 

especifi có con el límite superior 

Number

. Por esta razón se permite la línea 56, ya que todos los objetos 

Number

tienen un método 

doubleValue

.

Aunque los comodines proporcionan una fl exibilidad al pasar tipos parametrizados a un método, también 

tienen ciertas desventajas. Como el comodín (?) en el encabezado del método (línea 50) no especifi ca el nombre 
de un parámetro de tipo, no se puede utilizar como nombre de tipo en el cuerpo del método (es decir, no pode-
mos reemplazar 

Numero

 con 

?

 en la línea 55). Sin embargo, podríamos declarar el método 

sumar

de la siguiente 

manera:

public static

 <T 

extends

 Number> 

double

 sumar( ArrayList< T > lista )

lo cual permite al método recibir un objeto 

ArrayList

 que contenga elementos de cualquier subclase de 

Number

.

Después, podríamos usar el parámetro de tipo 

T

 en el cuerpo del método.

Si el comodín se especifi ca sin un límite superior, entonces sólo se pueden invocar los métodos del tipo 

Object

en valores del tipo del comodín. Además, los métodos que utilizan comodines en los argumentos de 

tipo de sus parámetros no pueden utilizarse para agregar elementos a una colección a la que el parámetro hace 
referencia.

18.8 Comodines en métodos que aceptan parámetros de tipo 

785

18_MAQ_CAP_18_DEITEL.indd785

4/19/081:30:51AM