2012-05-29 14 views
11

Código 1:valores Agregando arrayList

ArrayList arr = new ArrayList(); 
arr.add(3); 
arr.add("ss"); 

Código 2:

ArrayList<Object> arr = new ArrayList<Object>(); 
arr.add(3); 
arr.add("ss"); 

Código 3:

ArrayList<Object> arr = new ArrayList<Object>(); 
arr.add(new Integer(3)); 
arr.add(new String("ss")); 

todos los tres códigos anteriores están trabajando bien .. ¿Puede alguien dígame cuál es el preferido y por qué ... y por qué el compilador de eclipse siempre advierte cuando el tipo de argumentos no se mencionan en el Arraylist. Gracias en anuncio vance ..

Respuesta

10

Primera regla simple: nunca use el constructor String(String), es absolutamente inútil (*).

Así que arr.add("ss") está bien.

Con 3 es un poco diferente: 3 es un literal int, que no es un objeto. Solo los objetos se pueden poner en un List. Por lo tanto, el int deberá convertirse en un objeto Integer.En la mayoría de los casos, esto se hará automágicamente (ese proceso se llama autoboxing). Es efectivamente hace lo mismo que Integer.valueOf(3) que puede (y lo hará) evitar crear una nueva instancia Integer en algunos casos.

Así que en realidad es escribir arr.add(3) por lo general una mejor idea de utilizar arr.add(new Integer(3)), porque puede evitar la creación de un nuevo objeto y Integer lugar reutilizar y uno ya existente.

exención de responsabilidad: me estoy centrando en la diferencia entre los bloques segundo y tercer código aquí y bastante ignorando tanto la parte genéricos. Para obtener más información sobre los genéricos, consulte las otras respuestas.

(*) hay algunos casos oscuro rincón donde es útil, pero una vez que se acercan a las que nunca se darán cuenta de recabar declaraciones absolutas como absolutos ;-)

2

Bueno, al hacer lo anterior, se abre para ejecutar los errores de tiempo, a menos que esté contento de aceptar que sus listas de arreglos pueden contener tanto cadenas como enteros y elefantes.

Eclipse devuelve un error porque no quiere que desconozca el hecho de que al especificar ningún tipo para el parámetro genérico se está abriendo para los errores de tiempo de ejecución. Al menos con los otros dos ejemplos, usted sabe que puede tener objetos en su Arraylist y dado que Inetegers y Strings son ambos objetos, Eclipse no lo advierte.

Cualquiera de los códigos 2 o 3 está bien. Pero si usted sabe que tendrá, ya sea sólo enteros o sólo cadenas en su ArrayList entonces yo haría

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

o

ArrayList<String> arr = new ArrayList<String>(); 

respectivamente.

6

El segundo sería preferible:

  • evita constructor innecesaria/ineficiente llama
  • hace que se especifica el tipo de elemento de la lista (si es que falta, se obtiene una advertencia)

Sin embargo, tener dos tipos diferentes de objetos en la misma lista tiene un poco de mal olor de diseño. Necesitamos más contexto para hablar sobre eso. se prefiere

+2

Para explicar el último punto de @ Thilo, muchos desarrolladores de Java dirían que mezclar varios tipos en una 'Lista ' es el problema, y ​​que debe diseñar su código más cuidadosamente para preservar la seguridad del tipo. –

+1

Permítanme agregar mi nombre de anti-patrón favorito aún no reconocido aquí: mezclar tipos no relacionados en una sola lista huele a [negación del objeto] (http://stackoverflow.com/a/3725728/40342). –

3

La segunda forma:

ArrayList<Object> arr = new ArrayList<Object>(); 
arr.add(3); 
arr.add("ss"); 

Siempre especifique argumentos genéricos utilizando tipos genéricos (tales como ArrayList<T>). Esto descarta la primera forma.

En cuanto a la última forma, es más detallada y hace un trabajo extra sin ningún beneficio.

0

en la primera que Don 't definen el tipo que se llevará a cabo y se vincula dentro de su ArrayList construir

este es el método preferido para hacerlo, se define el tipo de lista y el IDE se encargará del resto

en el tercero se será mejor simplemente definir Lis t para el código más corto

+0

No ha mencionado ni indicado medicamentos genéricos, que es la esencia de esta pregunta. No es el IDE que "maneja el resto" sino el compilador. También "solo definir Lista" no es para código más corto: es el "Programa para una 'interfaz', no una regla de 'implementación' que es un tema mucho más grande. –

2

En realidad, un tercio se prefiere:

ArrayList<Object> array = new ArrayList<Object>(); 
array.add(Integer.valueOf(3)); 
array.add("ss"); 

Esto evita autoboxing (Integer.valueOf(3) frente 3) y no crea un objeto String innecesario.

Eclipse se queja cuando no utiliza argumentos de tipo con un tipo genérico como ArrayList, porque está utilizando algo llamado tipo sin formato, que se desaconseja. Si una clase es genérica (es decir, tiene parámetros de tipo), siempre debe usar argumentos de tipo con esa clase.

Autoboxing, por otro lado, es una preferencia personal. Algunas personas están de acuerdo con eso, y otras no. No me gusta, y enciendo la advertencia de autoboxing/autounboxing.

2

Recibirá la advertencia porque ArrayList es parte de java generics. Básicamente, es una forma de detectar los errores de tipo en el momento de la compilación. Por ejemplo, si declara su lista de matriz con tipos Entero (ArrrayList<Integer>) y luego intenta agregarle cadenas, obtendrá un error en tiempo de compilación, evitando bloqueos desagradables en tiempo de ejecución.

La primera sintaxis está ahí para la compatibilidad con versiones anteriores y debe evitarse siempre que sea posible (tenga en cuenta que los genéricos no estaban allí en las versiones anteriores de Java).

El segundo y el tercer ejemplo son prácticamente equivalentes. Como necesita pasar un objeto y no un tipo primitivo al método add, su 3 se convierte internamente en Integer(3). Al escribir una cadena entre comillas dobles, está creando efectivamente un objeto String. Al llamar al String("ss"), está creando un nuevo objeto String cuyo valor es el mismo que el parámetro ("ss").

A menos que realmente necesite almacenar diferentes tipos en su Lista, le sugiero que utilice una declaración de tipo adecuada, p. ArrayList<Integer> = new ArrayList<Integer>() - le ahorrará muchos dolores de cabeza a largo plazo.

Si necesita varios tipos de datos en la lista, entonces el segundo ejemplo es mejor.

2

Dos últimas variantes son iguales, int se envuelve automáticamente en Integer donde necesita Object. Si no escribe ninguna clase en <> será Object de forma predeterminada. Entonces no hay diferencia, pero será mejor entender si escribe Object.

Cuestiones relacionadas