List versus ArrayList as reference type?
Ok so I know that Set
, List
and Map
are interfaces but what makes the first line of code any better than the second line?
List myArr = new ArrayList();
ArrayList myArr = new ArrayList();
Solution 1:
If you use the first form, you are saying all you are ever going to use is the functionality of the List
interface - nothing else, especially nothing extra added by any implementation of it. This means you can easily change the implementation used (e.g. just substitute LinkedList
for ArrayList
in the instantiation), and not worry about it breaking the rest of the code because you might have used something specific to ArrayList
.
Solution 2:
A useful general principle about types in programming (sometime referred to as the robustness principle) is as follows:
- Be liberal about what you accept
- Be conservative about what you emit
List is more liberal than ArrayList, since List can be any kind of List implementation e.g. an ArrayList, a LinkedList or FrancosSpecialList. Hence it is a good idea to be liberal and accept any kind of list since you may want to change the implementation later.
The main reason to use ArrayList explicitly as a type (your second case) is if you need to use methods that are specific to ArrayList that are not available through the List interface. In this case a generic List won't work (unless you want to do lots of ugly and confusing casting), so you might as well be explicit and use an ArrayList directly. This has the added bonus of hinting to a reader that specific features of ArrayList are needed.
Solution 3:
As you can see from the source of ArrayList
here, most of the methods implemented are annotated as @override
because all of them that are defined through List
interface so, if you are gonna use just basic functionalities (that is what you are gonna do most of the time) the difference won't be any practical one.
The difference will come if someday you will think that the features of the ArrayList
are not suitable anymore for your kind of problem and you will need something different (a LinkedList
for example). If you declared everything as List
but instantiated as ArrayList
you will easily switch to new implementation by changing the instantiations to new LinkedList()
while in other case you will have to change also all variable declarations.
Using List list = new ArrayList()
is more OOP style since you declare that you don't care about the specific implementation of the list, and that you want to discard the static information about the type since you will rely on the interface provided by this kind of collection abstracting from its implementation.