2011-03-30 16 views
11

¿Cuál es la diferencia en la declaración de una colección como tal¿Debo declarar/Inicializar ArrayLists como listas, ArrayLists, o ArrayLists de <Cat>

public class CatHerder{ 
    private List cats; 
    public CatHerder(){ 
     this.cats = new ArrayList<Cat>(); 
    } 
} 
//or 
public class CatHerder{ 
    private ArrayList cats; 
    public CatHerder(){ 
     this.cats = new ArrayList(); 
    } 
} 
//or 
public class CatHerder{ 
    private ArrayList<Cat> cats; 
    public CatHerder(){ 
     this.cats = new ArrayList<Cat>(); 
    } 
} 

Respuesta

22

Debe declarará como List<Cat>, e inicializar como una ArrayList<Cat>.

List es una interfaz y ArrayList es una clase de implementación. Casi siempre es preferible codificar contra la interfaz y no la implementación. De esta forma, si necesita cambiar la implementación más tarde, no romperá a los consumidores que codifican contra la interfaz.

Dependiendo de cómo utilice realmente la lista, es posible que incluso pueda utilizar la menos específica java.util.Collection (una interfaz que se extiende a List).

En cuanto a List<Cat> (se puede leer que, como "lista de gato") vs List: eso es Java de generics, que aseguran en tiempo de compilación Tipo de manera segura. En resumen, permite al compilador asegurarse de que el List solo contiene objetos Cat.


public class CatHerder{ 
    private final List<Cat> cats; 
    public CatHerder(){ 
     this.cats = new ArrayList<Cat>(); 
    } 
} 
+2

y márquelo como final, si lo configura solo en el constructor. – Puce

+0

@Puce: buen punto. –

+0

He visto este argumento usado muchas veces antes. Pero, ¿en qué circunstancia verías realmente que es necesario declarar el tipo de interfaz? ¿Hay algún caso de uso en el que uno inicialice un tipo de colección específico, agregue datos y luego, un poco más tarde, cambie de opinión sobre el tipo de colección? –

1

Con el fin de garantizar la seguridad de tipos, y debido a los compiladores Java actuales se quejan si un tipo genérico no tiene ningún argumento de tipo, siempre debe especificar un tipo de forma explícita - o <?> si realmente no se preocupan .

Dicho esto, a menos que use algo específico para la clase ArrayList, debe usar List<Cat> para evitar vincular su código a una implementación particular de List.

4

yo haría lo siguiente.

public class CatHerder{ 
    private final List<Cat> cats = new ArrayList<Cat>(); 
} 
+1

6 años después, asumiendo java 7+ Prefiero inicializar con List cats = nueva ArrayList <>() ;. Lo recogí del plugin eclipse sonar. Citando la Id. De regla de Sonar 2293, "Java 7 introdujo el operador de diamante (<>) para reducir la verbosidad del código genérico. Por ejemplo, en lugar de tener que declarar un tipo de Lista tanto en su declaración como en su constructor, ahora puede simplificar el constructor declaración con <>, y el compilador inferirá el tipo ". – kyle

1

Como ya mencioné, usar la interfaz/superclase más común es la mejor manera de hacerlo aquí. Asegúrese de declarar siempre el tipo que aparece en la lista, de modo que sea un List<Cat> o incluso List<? extends Cat>

Si, en algún momento posterior, que desea reemplazar el ArrayList con, por ejemplo, un LinkedList, no lo hará tiene que cambiar la declaración, pero solo la instanciación.

1

List es más flexible que ArrayList, List<Cat> es más seguro que List. entonces List<Cat> es una buena opción.

1

En primer lugar, List es una interfaz y ArrayList es una implementación de la interfaz List (en realidad, subclases y AbstractListimplements List). Por lo tanto List cats = new ArrayList() es válido, ya que ArrayListes un-List.

Por esta:

private List cats; 

cats se convierte en un tipo de prima (no hay ninguna referencia al tipo genérico para List), no ha sido parametrizado.

Su tercera solución es correcta (que resuelve su problema para la opción 1),

private ArrayList<Cat> cats; 

que ha delimitado un tipo genérico E para List<E> a un tipo Cat. Por lo tanto, su creación de instancias de cats es válida ya que el límite genérico es el mismo.

Su segunda solución permite que solo se pueda crear una instancia de ArrayList de cats. Las otras 2 opciones le permiten instanciar cualquier objeto que es-aList, p. Ej. LinkedList.

Cuestiones relacionadas