问题
I've seen code like this many times:
List<String> list = new ArrayList<String>();
Why do people take the parent of ArrayList
(and other classes) instead of the type of the generated object?
Does that take less performance? Or why should someone do this?
回答1:
When someone writes code like this, he/she is trying to follow a basic OO design principle which says -
Program to an interface, not to a concrete implementation
I have explained this principle in one of my blog posts. Look in the Class Inheritance VS Interface Inheritance
section.
To summarize the post, when you use a reference of a parent type to refer to an instance of a sub-type, you get a lot of flexibility. For example, if you ever need to change your sub-type implementation in the future, you will be able to do that easily, without changing much of your code.
Consider the following method -
public void DoSomeStuff(Super s) {
s.someMethod();
}
and a call to this method -
DoSomeStuff(new Sub());
now, if you ever need to change the logic inside someMethod
, you can easily do it by declaring a new subtype of Super
, say NewSubType
, and changing the logic inside that implementation. In this way, you will never have to touch other existing code which utilizes that method. You will still be able to use your DoSomeStuff
method in the following way -
DoSomeStuff(new NewSubType());
Had you declared the parameter of DoSomeStuff
to be of Sub
, you would then have to change its implementation too -
DoSomeStuff(NewSubType s) {
s.someMethod();
}
and it may also chain/bubble to several other places.
In terms of your collection example, this lets you change the list implementation that a variable is pointing to without much hassle. You can easily use a LinkedList
in place of an ArrayList
.
回答2:
When you write:
List<String> list = new ArrayList<String>();
Then you are sure you'll use only the functionality of the interface List.
(ArrayList
implements List
, so List
is more flexibl).
Using this, allows you to change the ArrayList
to other types in the future (like LinkedList
..).
回答3:
It means you can swap out the type of list
at any point with anything that implements the List
interface, as opposed to creating a rigid model that can only use ArrayList
. For example:
private List<String> list;
public SomeConstructor()
{
// At this point, you can make it any type of object you want.
list = new ArrayList<String>();
list = new LinkedList<String>();
list = new AttributeList<String>();
}
This will abstract
your code that uses the list
object, away from the details like what exact object type list
is. All it needs to know is that it has the add
method etc. This is called Loose Coupling.
回答4:
To sort things out:
For more flexibility you initiate interface List
:
So if you don't need all ArrayList
use List
only.
You can write something like: List<String> = Arrays.asList("aa", "bb","cc")
.
For sure, less functionality can help to performance. As you know If you want to use multithreaded application, use Vector
instead but it will down your performance.

Took from here
回答5:
Because a method doesn't have to know what list-implementation you use.
A Method just needs to know that is is a list.
The Method can still be used.
Always program to an interface, not to a concrete implementation. (In this case List)
回答6:
Generally it is preferred to work with the Interface class (List
in this case) so that any List implementation could later be substituted with minimal fuss if requirements change.
Although ArrayList
possibly supports some methods that are not on the List
interface, this declaration makes it clear that those extra methods are not relevant in that case.
回答7:
List<String> list = new ArrayList<String>();
In collection framework List
is an interface while ArrayList
is implementation. Main reason you'd do this is to decouple your code from a specific implementation
of the interface also this will be helpful in case if you wish to move to some other implementation of List
in the future.
来源:https://stackoverflow.com/questions/18329311/reason-for-list-list-new-arraylist