Ok, sé que Set
, List
y Map
son interfaces, pero ¿qué hace que la primera línea de código sea mejor que la segunda línea?Lista frente a ArrayList como tipo de referencia?
List myArr = new ArrayList();
ArrayList myArr = new ArrayList();
Ok, sé que Set
, List
y Map
son interfaces, pero ¿qué hace que la primera línea de código sea mejor que la segunda línea?Lista frente a ArrayList como tipo de referencia?
List myArr = new ArrayList();
ArrayList myArr = new ArrayList();
Si utiliza la primera forma, que está diciendo todo lo que siempre se va a utilizar es la funcionalidad de la interfaz List
- nada más, nada en especial extra añadido por cualquier implementación de la misma. Esto significa que puede cambiar fácilmente la implementación utilizada (por ejemplo, simplemente sustituya LinkedList
por ArrayList
en la creación de instancias), y no se preocupe si rompe el resto del código porque es posible que haya utilizado algo específico para ArrayList
.
Creo que el caso se puede hacer más convincente cuando menciona el ajuste de ArrayList en Collections.checkedList() para la depuración. Cuando mencionas LinkedList, la gente dice "¿por qué alguna vez usar LinkedList?". – ILMTitan
@ILMTitan: De acuerdo.Ese es un escenario mucho más común que tener que cambiar a 'LinkedList'. Pero 'LinkedList' es útil también, tuve que cambiar a usarlos cada vez que necesitaba hacer muchas adiciones/eliminaciones al principio. El punto principal aquí es separar la implementación y la interfaz para que la implementación pueda cambiar sin tener que realizar muchos cambios en el resto del código. – MAK
Como se puede ver en la fuente de ArrayList
here, la mayoría de los métodos implementados anotados como @override
porque todos ellos que se definen a través List
interfaz es así, si estás a usar funcionalidades sólo los de base (que es lo que está va a hacer la mayor parte del tiempo) la diferencia no será práctica.
La diferencia vendrá si algún día piensas que las características del ArrayList
ya no son adecuadas para tu tipo de problema y necesitarás algo diferente (un LinkedList
por ejemplo). Si declaró todo como List
pero instanciado como ArrayList
, cambiará fácilmente a la nueva implementación cambiando las instancias a new ArrayList()
, mientras que en el otro caso deberá cambiar también todas las declaraciones de variables.
El uso de List list = new ArrayList()
es más estilo OOP ya que declara que no le importa la implementación específica de la lista, y que desea descartar la información estática sobre el tipo ya que dependerá de la interfaz proporcionada por este tipo de la recopilación de resúmenes de su implementación.
Un principio general útil sobre tipos de programación (Algunas veces nos referimos como el robustness principle) es como sigue:
La lista es más liberal que ArrayList, ya que List puede ser cualquier tipo de implementación de lista, por ejemplo una ArrayList, LinkedList o FrancosSpecialList. Por lo tanto, es una buena idea ser liberal y aceptar cualquier tipo de lista ya que es posible que desee cambiar la implementación más adelante.
La razón principal para usar ArrayList explícitamente como tipo (su segundo caso) es si necesita usar métodos que son específicos de ArrayList que no están disponibles a través de la interfaz de la Lista. En este caso, una Lista genérica no funcionará (a menos que desee hacer muchos lanzamientos feos y confusos), por lo que también podría ser explícito y utilizar una ArrayList directamente. Esto tiene la ventaja adicional de insinuarle a un lector que se necesitan características específicas de ArrayList.
La segunda línea es mejor porque el tipo ArrayList proporciona más funcionalidad además de la Lista. Sin embargo, el tipo de lista es mejor cuando se utiliza un código que no depende de la implementación de la lista. Por favor, cubra mi [Vida interna de ArrayList] (http://volodial.blogspot.com/2013/07/internal-life-of-arraylist-in-java.html) para conocerla más profundamente. –