Use interface or type for variable definition in java?

Solution 1:

List is an Interface, whereas ArrayList is an implementation of that interface.

The second is better because it means you can change your ArrayList for another implementation of List later without needing to change the rest of your application. You may want to do this for performance reasons, or because of other aspects of the behaviour of the List implementation that you have chosen/will choose.

Solution 2:

Both are deprecated since Java 1.5.

It should be:

List<String> list = new ArrayList<String>();
// or whatever data type you are using in your list

Please read Effective Java by Joshua Bloch, especially these two items:

  • 23: Don't use raw types in new code (this is even available online)
  • 52: Refer to objects by their interfaces

BTW, if you use Guava, you have a factory method for constructing an ArrayList so you don't have to repeat the type parameter:

List<String> list = Lists.newArraylist();

Solution 3:

List<T> is interface, where ArrayList<T> is class, and this class implements List<T> interface.

I would prefer 2nd form, which is more general, ie if you do not use methods specific to ArrayList<T> you can declare its type as interface List<T> type. With 2nd form it will be easier to change implementation from ArrayList<T> to other class that implements List<T> interface.

EDIT: As many of SO users commented both forms can be arguments to any method that accept List<T> or ArrrayList<T>. But when I declare method I would prefer interface:

 void showAll(List <String> sl) ...

and use:

 void showAllAS(ArrayList <String> sl) ...

only when my method uses method specific to ArrayList<T>, like ensureCapacity().

Response with information that we should use typed List<T> instead of just List is very good (of course if we do not use ancient Java).

Solution 4:

All these answers are the same recite from some dogma they read somewhere.

A variable declaration and initialization statement, Type x = new Constructor();, is definitely part of implementation detail. It's not part of a public API (unless it's public final, but List is mutable so that's inappropriate)

As an implementation detail, who you are trying to fool with your abstractions? It's better to keep the type as specific as possible. Is it an array list or a linked list? Should it be thread safe or not? The choice is important for your implementation, you carefully chose the specific list impl. Then you declare it as a mere List as if it doesn't matter and you don't care?

The only legitimate reason to declare it as List is I'm too lazy to type. That also covers the argument that if I need to move to another List impl I have one less place to modify.

This reason is legitimate only when the variable scope is small, and you can see all of its usages from one glance. Otherwise, keep the most specific type, so that its performance and semantic characteristics are manifest across all the code that use the variable.

Solution 5:

I prefer the second in most cases because it signifies that you're not using anything specific in the ArrayList api, and if you need to later you can substitute any other type of List without having to change any code except the first line.