2012-01-19 8 views
5

Tengo una pregunta sobre el uso de genéricos con colecciones.Colección con genéricos

ArrayList<Integer> al=new ArrayList<Integer>(); 

Sabemos que la línea anterior significa que ArrayListal se limita a contener sólo números enteros. Así que la siguiente línea da un error de compilación:

al.add("wwww"); 

Pero no entiendo lo que significa que la línea de abajo,

ArrayList al=new ArrayList<Integer>(); 

Cuando no damos ArrayList<Integer> en el lado izquierdo, mientras que declarar. Ahora la siguiente línea no dar un error de compilación:

al.add("wwww"); 

Así que si me declaro como

ArrayList al=new ArrayList<Integer>(); 

que significa a1 puede aceptar cualquier tipo?

¿Cuál es la diferencia entre esas dos declaraciones?

Respuesta

5

Con este código:

ArrayList al = new ArrayList<Integer>(); 
a1.add("www"); 

el compilador generará una advertencia (que se debe prestar atención!), Pero el código se ejecutará sin error. El problema surge al extraer datos del a1. Si se "sabe" que contiene Integer valores, puede simplemente hacer esto:

Integer val = (Integer) a1.get(index); 

Pero cuando se pulse el elemento "www" vas a conseguir un ClassCastException. Los genéricos están destinados a mover dichos errores para compilar el tiempo en lugar de obligar al desarrollador deficiente a rastrear cómo un valor String terminó en esa lista de matriz Integer.

9

Esta última declaración (sin tipo genérico) es obsoleto y en desuso. No deberías usarlo, compila solo por compatibilidad con versiones anteriores. Los IDE modernos generarán advertencias aquí.

También tenga en cuenta que Java sólo se aplica tipos genéricos en tiempo de compilación, por lo que técnicamente se puede añadir tipo incorrecto de una colección con algunos moldes adicionales. Es por eso que es mejor quedarse con los genéricos todo el tiempo y no pasar por alto.

+1

... y su IDE (si está utilizando uno) probablemente muestre una advertencia. – Axel

+0

@Axel: +1. Independientemente, agregué el mismo comentario a mi respuesta, debes creerme ;-). –

+0

Por alguna razón a partir del 7 las personas de netbeans desactivadas muestran las advertencias de javac estándar de forma predeterminada. (y un aumento significativo en decir internos "corregir sus advertencias de tipo raw") – Affe

0

Esta última declaración es básicamente el mismo que:

ArrayList<Object> al=new ArrayList<Object>(); 

aceptando así cualquier objeto. No debe usarse, y es posible usarlo para que Java sea compatible con versiones anteriores (anterior a Java1.5).

0

debe escribir como este ArrayList<Integer> al=new ArrayList<Integer>(); para evitar agregar objetos a su lista con otros tipos porque verá el tiempo de compilación del error. Por supuesto puede usar ArrayList al=new ArrayList<Integer>(); pero debe tener cuidado. En otras palabras, siempre use el primero: D

0

Los genéricos se implementan por borrado de tipo: la información de tipo genérico está presente solo en tiempo de compilación, después de lo cual es borrado por el compilador. Entonces, la declaración ArrayList al permite que el compilador acepte cualquier tipo. Aquí está java doc sobre este tema.

0

Este tipo de declaración se permite por compatibilidad con versiones anteriores. Así puede por ejemplo que pasar lista genérica con el método del viejo estilo de la biblioteca wich acepta lista sólo prima:

List<Integer> list = new ArrayList<Integer>(); 
OldStyledClass.method(myArray); 

donde se declara un método similar:

public static void method(List list)... 

En este caso usted tiene alguna especial métodos de utilidad en java.util.Collections. Lo que puede pasar a esta lista de especies protegidas método:

OldStyledClass.method(Collections.checkedList(myArray, Integer.class)); 

Si el método intentará poner en su lista de objetos de algún otro tipo obtendrá immediatley ClassCastException.

Cuestiones relacionadas