7

Below are two ways how to create ArrayList:

List<String/*or other object*/> arrList = new ArrayList();//Imports List, ArrayList
ArrayList<String/*or other object*/> arrList = new ArrayList();//Imports just ArrayList

What is the difference? Which method should be used?

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
Ernestas Gruodis
  • 8,567
  • 14
  • 55
  • 117

9 Answers9

6

The first form is recommended for the public interface of a class (say, the declaration of the attributes in a class). It's a well-known advice that you should program for an interface, not for a concrete implementation (this is stated in Design Patterns) - the number of classes you have to import has little to do with the quality of code and good design.

The advantage of the first form is that it'll allow you to easily swap implementations later on, if the need arises - whereas the second implementation sets in stone the implementing class, making your code harder to evolve and less flexible.

There are cases when it's OK to declare and use concrete classes, though (for instance, for a little bump in performance). But the public interface of a class should use interfaces whenever possible, it'll make future changes easier to implement.

Óscar López
  • 232,561
  • 37
  • 312
  • 386
  • When I read the question, I was sure that within seconds there will be a lot of people giving this or a similar answer (if nobody had, I would have ;)). However, in 15 years as a programmer, there has never been a real live problem coming up by ignoring the rule you described, nor did I ever had any profit by following it. So do you have an example from your programming live, which really encourages everybody to never, never, NEVER program against concrete classes? – Kai Huppmann Aug 28 '13 at 15:52
  • @KaiHuppmann for performance reasons it's ok to declare and use concrete classes (say, as local variables in a method). But the public interface of a class should be exposed in terms of interfaces. That has served me well :) – Óscar López Aug 28 '13 at 15:54
  • @KaiHuppmann well they are all wrong:) – ZhongYu Aug 28 '13 at 16:01
  • It is however important to remember that the disadvantage of the first form is that it prohibits you to use the functionality of ArrayList which extends the functionality exposed by the List interface. ArrayList also implements the interfaces RandomAccess, Serializable and Cloneable, which are not implemented by List. Additionally, ArrayList offers the methods ensureCapacity and trimToSize to access functionality especially offered by ArrayList (and not necessarily other List implementations). – jarnbjo Aug 28 '13 at 16:02
  • *"for a little bump in performance"* In what way will using concrete classes improve performance? – arshajii Aug 28 '13 at 16:14
  • @arshajii not "using", "declaring" a variable as a concrete class instead of an interface might have a small performance improvement. This used to be true at the time [Java Performance Tuning](http://www.amazon.com/Java-Performance-Tuning-Jack-Shirazi/dp/B00CVE709W) was written, check that book for reference. It all boils down to the time it takes to perform a method lookup – Óscar López Aug 28 '13 at 16:31
2

First ways is called coding to interface

Second one is called coding to implementation.

The advantage with the second one is that it gives you the flexibility to change the implemneatation class later without any code change. For example today you are using ArrayList but if tomorrow you want to change it to LinkedList then simply change the implmentation class in your list definition.

Juned Ahsan
  • 67,789
  • 12
  • 98
  • 136
1

By doing it like the first example, you are able to assign the List to any datastructure implementing the List interface.

This adds flexibility to your program, because you are able to change the implementation easily.

Daniel Mac
  • 400
  • 2
  • 14
1

The first one leaves you free to change the concrete class (ArrayList) if you later realise that another implementation of List is better suited to your task. You would only need to change that one line, as the other places using arrList expect anything that implements List, not an ArrayList.

With the second version, if you decide to make that change, you will have to change every place that expects an ArrayList.

As mentioned above, this is called coding to the interface.

matt freake
  • 4,877
  • 4
  • 27
  • 56
0

List is an interface. ArrayList is a class that implements the List interface.

Jordan57
  • 11
  • 5
0

The difference is it hides the specific implementation from callers of methods that return List. This is generally good practice - If you return List then you have the freedom to later change the underlying implementation without having to worry about a ripple effect of changing a bunch of other code. IF you don't need the List-specific things like List.get(index) you could even go a step further and simply specify Collection<String> col = new ArrayList<String();

StormeHawke
  • 5,987
  • 5
  • 45
  • 73
0

If you want to create an ArrayList, only the second is correct. The first creates a List, which is implemented by the ArrayList class, but they aren't interchangeable in many circumstances. This question has a pretty good answer.

Community
  • 1
  • 1
ajiang
  • 1,702
  • 2
  • 12
  • 12
0

Contrary to popular opinion, I say we should use the 2nd form

ArrayList<X> list = new ArrayList<>();

This line is an implementation detail; we should be as specific as possible in our implementation details.

It's not part of a public API that should be abstracted; arguments for "code against interface" do not apply here.

ZhongYu
  • 19,446
  • 5
  • 33
  • 61
0

I can see that many people recommends using the interface, I'd say the following :

  • If you think the person using your code really needs to know the details of the implementation you are using, use the concrete class. For example, if you are writing a high performance library that has methods returning a particular implementation such as LinkedList which requires special care in handling)..

  • In most other cases, when you can avoid exposing too much detail, use interfaces.

Stéphane C.
  • 1,801
  • 2
  • 16
  • 12