(1) is good practice, it avoid to tie-up with a particular implementation with help of Interface(List)
example: pretend List has a method called soccerWinner() and ArrayList and LinkedList both overriden that method as below
if you declare as ArrayList a = new ArrayList(); then you endup with ArrayList specific implementation[you tend to call the method possibility] . if tomorrow you want to go for LinkedList, then it requires drastic existing code change right?
if you were declare as List a = new ArrayList(); then just you need to replace ArrayList by LinkedList; minimal code change[change in one line].
hence, (1) is a good practice.
anyway, this topic has been discussed many time here . search here, if you want more clarification
There really isn't that much of a difference between the two reference declarations shown. Since both mention ArrayList by name, both are tightly coupled to that implementation. In practice, as long as you don't call any ArrayList specific methods on the list (and really, why would you?) they're both just as painless to refactor to a different list implementation. The first declaration is generally preferred because it is more idomatic Java.
The place programming to an interface really shines is within a method definition. Consider the following definitions:
The second declaration is much more general and flexible. You can call the method with an ArrayList, LinkedList, Stack, Vector, a List returned from Arrays.asList(), or any one of the infinite possible List implementations that weren't even on the class path when this method was compiled. It's more flexible and therefore more reusable, which is a very Good Thing.
Programming to an interface is also a Good Thing when considering the type that a method returns:
What if the publisher of the library that contains this method decides in version 2.0, that ArrayList isn't the right choice and he really should have returned a LinkedList? With the first version, his hands are tied. He would break any code out there that depended on the fact that this method returned an ArrayList. He would just have to leave it as is for fear of breaking client code. In the second version, the author is free to change the implementation as he sees fit. Client code shouldn't rely on the fact that any specific List type will be returned (and if they do, then they deserve to get broken) so changing implementations should be transparent to the user of the method.
Don't think this will ever come up? Consider all the legacy code in the JDK which takes a Vector as a parameter. The authors of the code never considered the fact that something better may come along. so they programmed to a specific type instead of factoring out an interface to program to. Once that choice is made it can't be easily undone.
Some problems are so complex that you have to be highly intelligent and well informed just to be undecided about them. - Laurence J. Peter