By kji

2010-02-17 07:40:13 8 Comments

(1) List<?> myList = new ArrayList<?>();

(2) ArrayList<?> myList = new ArrayList<?>();

I understand that with (1), implementations of the List interface can be swapped. It seems that (1) is typically used in an application regardless of need (myself I always use this).

I am wondering if anyone uses (2)?

Also, how often (and can I please get an example) does the situation actually require using (1) over (2) (i.e. where (2) wouldn't suffice..aside coding to interfaces and best practices etc.)


@Stephen C 2010-02-17 07:50:13

I am wondering if anyone uses (2)?

Yes. But rarely for a sound reason (IMO).

And people get burned because they used ArrayList when they should have used List:

  • Utility methods like Collections.singletonList(...) or Arrays.asList(...) don't return an ArrayList.

  • Methods in the List API don't guarantee to return a list of the same type.

For example of someone getting burned, in the poster had problems with "slicing" because ArrayList.sublist(...) doesn't return an ArrayList ... and he had designed his code to use ArrayList as the type of all of his list variables. He ended up "solving" the problem by copying the sublist into a new ArrayList.

The argument that you need to know how the List behaves is largely addressed by using the RandomAccess marker interface. Yes, it is a bit clunky, but the alternative is worse.

Also, how often does the situation actually require using (1) over (2) (i.e. where (2) wouldn't suffice..aside 'coding to interfaces' and best practices etc.)

The "how often" part of the question is objectively unanswerable.

(and can I please get an example)

Occasionally, the application may require that you use methods in the ArrayList API that are not in the List API. For example, ensureCapacity(int), trimToSize() or removeRange(int, int). (And the last one will only arise if you have created a subtype of ArrayList that declares the method to be public.)

That is the only sound reason for coding to the class rather than the interface, IMO.

(It is theoretically possible that you will get a slight improvement in performance ... under certain circumstances ... on some platforms ... but unless you really need that last 0.05%, it is not worth doing this. This is not a sound reason, IMO.)

You can’t write efficient code if you don’t know whether random access is efficient or not.

That is a valid point. However, Java provides better ways to deal with that; e.g.

public <T extends List & RandomAccess> void test(T list) {
    // do stuff

If you call that with a list that does not implement RandomAccess you will get a compilation error.

You could also test dynamically ... using instanceof ... if static typing is too awkward. And you could even write your code to use different algorithms (dynamically) depending on whether or not a list supported random access.

Note that ArrayList is not the only list class that implements RandomAccess. Others include CopyOnWriteList, Stack and Vector.

I've seen people make the same argument about Serializable (because List doesn't implement it) ... but the approach above solves this problem too. (To the extent that it is solvable at all using runtime types. An ArrayList will fail serialization if any element is not serializable.)

@Acuna 2018-06-15 21:38:04

List interface have several different classes - ArrayList and LinkedList. LinkedList is used to create an indexed collections and ArrayList - to create sorted lists. So, you can use any of it in your arguments, but you can allow others developers who use your code, library, etc. to use different types of lists, not only which you use, so, in this method

ArrayList<Object> myMethod (ArrayList<Object> input) {
   // body

you can use it only with ArrayList, not LinkedList, but you can allow to use any of List classes on other places where it method is using, it's just your choise, so using an interface can allow it:

List<Object> myMethod (List<Object> input) {
   // body

In this method arguments you can use any of List classes which you want to use:

List<Object> list = new ArrayList<Object> ();

list.add ("string");

myMethod (list);


Use the interfaces everywhere when it possible, don't restrict you or others to use different methods which they want to use.

@toxicafunk 2016-12-23 11:06:00

Somebody asked this again (duplicate) which made me go a little deeper on this issue.

public static void main(String[] args) {
    List<String> list = new ArrayList<String>();

    ArrayList<String> aList = new ArrayList<String>();


If we use a bytecode viewer (I used weĺl see the following (only list initialization and assignment) for our list snippet:

    NEW ArrayList
    INVOKESPECIAL ArrayList.<init> () : void
    ASTORE 1
    ALOAD 1: list
    LDC "a"
    INVOKEINTERFACE List.add (Object) : boolean
    ALOAD 1: list
    LDC "b"
    INVOKEINTERFACE List.add (Object) : boolean

and for alist:

    NEW java/util/ArrayList
    INVOKESPECIAL java/util/ArrayList.<init> ()V
    ASTORE 2
    ALOAD 2
    LDC "a"
    INVOKEVIRTUAL java/util/ArrayList.add (Ljava/lang/Object;)Z
    ALOAD 2
    LDC "b"
    INVOKEVIRTUAL java/util/ArrayList.add (Ljava/lang/Object;)Z

The difference is list ends up calling INVOKEINTERFACE whereas aList calls INVOKEVIRTUAL. Accoding to the Bycode Outline Plugin reference,

invokeinterface is used to invoke a method declared within a Java interface

while invokevirtual

invokes all methods except interface methods (which use invokeinterface), static methods (which use invokestatic), and the few special cases handled by invokespecial.

In summary, invokevirtual pops objectref off the stack while for invokeinterface

the interpreter pops 'n' items off the operand stack, where 'n' is an 8-bit unsigned integer parameter taken from the bytecode. The first of these items is objectref, a reference to the object whose method is being called.

If I understand this correctly, the difference is basically how each way retrieves objectref.

@Stephen C 2017-08-28 22:42:18

Ermm ... this analysis is moot. In reality, the JIT compiler performs global analysis to determine if method calls need to do virtual (dispatching) method calls. Many / most INVOKEVIRTUAL bytecode instructions turn into non-dispatching call sequences at the native code level.

@raudi 2016-11-14 10:22:30

Actually there are occasions where (2) is not only preferred but mandatory and I am very surprised, that nobody mentions this here.


If you have a serializable class and you want it to contain a list, then you must declare the field to be of a concrete and serializable type like ArrayList because the List interface does not extend

Obviously most people do not need serialization and forget about this.

An example:

public class ExampleData implements {

// The following also guarantees that strings is always an ArrayList.
private final ArrayList<String> strings = new ArrayList<>();

@Stephen C 2017-11-13 11:12:53

In practice, there are few cases where you need to know at compile time that the implementation class of some variable implements Serializable. And when you do, you can do something like this: public <T extends List & Serializable> void test(T list) { ... }.

@Xar-e-ahmer Khan 2015-10-27 11:50:44

List is an interface.It doesn't have methods. When you call method on a List reference. It in fact calls the method of ArrayList in both cases.

And for future you can change List obj = new ArrayList<> to List obj = new LinkList<> or other type which implements List interface.

@Jean-Christophe Blanchard 2017-05-23 13:38:20

You should say it differently : List has method but they are not implemented You cant't say "It doesn't have methods."

@i_am_zero 2015-07-03 08:40:04

Out of the following two:

(1) List<?> myList = new ArrayList<?>();
(2) ArrayList<?> myList = new ArrayList<?>();

First is generally preferred. As you will be using methods from List interface only, it provides you the freedom to use some other implementation of List e.g. LinkedList in future. So it decouples you from specific implementation. Now there are two points worth mentioning:

  1. We should always program to interface. More here.
  2. You will almost always end up using ArrayList over LinkedList. More here.

I am wondering if anyone uses (2)

Yes sometimes (read rarely). When we need methods that are part of implementation of ArrayList but not part of the interface List. For example ensureCapacity.

Also, how often (and can I please get an example) does the situation actually require using (1) over (2)

Almost always you prefer option (1). This is a classical design pattern in OOP where you always try to decouple your code from specific implementation and program to the interface.

@Maxim Shoustin 2014-09-09 15:12:05

For example you might decide a LinkedList is the best choice for your application, but then later decide ArrayList might be a better choice for performance reason.


List list = new ArrayList(100); // will be better also to set the initial capacity of a collection 

Instead of:

ArrayList list = new ArrayList();

For reference:

enter image description here

(posted mostly for Collection diagram)

@nazar_art 2013-08-21 11:46:38

It is considered good style to store a reference to a HashSet or TreeSet in a variable of type Set.

Set<String> names = new HashSet<String>();

This way, you have to change only one line if you decide to use a TreeSet instead.

Also, methods that operate on sets should specify parameters of type Set:

public static void print(Set<String> s)

Then the method can be used for all set implementations.

In theory, we should make the same recommendation for linked lists, namely to save LinkedList references in variables of type List. However, in the Java library, the List interface is common to both the ArrayList and the LinkedList class. In particular, it has get and set methods for random access, even though these methods are very inefficient for linked lists.

You can’t write efficient code if you don’t know whether random access is efficient or not.

This is plainly a serious design error in the standard library, and I cannot recommend using the List interface for that reason.

To see just how embarrassing that error is, have a look at the source code for the binarySearch method of the Collections class. That method takes a List parameter, but binary search makes no sense for a linked list. The code then clumsily tries to discover whether the list is a linked list, and then switches to a linear search!

The Set interface and the Map interface, are well designed, and you should use them.

@ToolmakerSteve 2015-09-13 16:34:39

Upvoted for saying specifically what the problem is in hiding ArrayList vs LinkedList behind List.

@Akash Agarwal 2016-01-26 05:09:51

This deserves more upvotes. Cleared my doubt if I should continue using ArrayList or List. If I'm seeking performance and I don't need random access, ArrayList is the answer!

@Stephen C 2016-11-22 02:59:28

Note however, that there is a marker interface called RandomAccess that is applied to all standard List subclasses that have efficient random access. For instance ArrayList implements this, and LinkedList doesn't. You can use this to choose between algorithms that require random access or not.

@kgiannakakis 2010-02-17 07:46:11

Almost always the first one is preferred over the second one. The first has the advantage that the implementation of the List can change (to a LinkedList for example), without affecting the rest of the code. This will be a difficult task to do with an ArrayList, not only because you will need to change ArrayList to LinkedList everywhere, but also because you may have used ArrayList specific methods.

You can read about List implementations here. You may start with an ArrayList, but soon afterwards discover that another implementation is more appropriate.

@kji 2010-02-17 07:48:17

can you elaborate on changing the implementation of the List? Using my code as an example, to change myList to a LinkedList, wouldn't one still need to call new LinkedList() on the myList?

@kji 2010-02-17 07:49:09

oh I commented before your last addition was there..but it all makes sense now..thanks

@kgiannakakis 2010-02-17 07:49:34

Yes, and this will be the only code change you will need. Compare with with changing ArrayList to LinkedList in every method. Not to mention having to replaca an ArrayList only method.

@Blrp 2014-12-03 02:05:29

"but also because you may have used ArrayList specific methods" - isn't this an argument for using ArrayList? If you use List, you can't use ArrayList specific methods.

@kgiannakakis 2014-12-03 08:23:38

@Blrp: The cases that you do need to use ArrayList specific methods are limited. In that case you can very easily convert your List to ArrayList very easily. Most common is to accidentally use an ArrayList method, without that being necessary. Changing ArrayList to List or another List implementation is difficult.

@Rogue 2015-03-12 23:11:46

Something to note is that "ArrayList specific methods" isn't limited to just methods used in ArrayList, but their return types being changed as well (will cause a NoSuchMethodException between Java versions if the internal return type changes). An example of this is the change in the return type of keySet in ConcurrentHashMap between Java 7 and 8.

@Jwan622 2016-01-05 20:42:54

So why use ArrayList or LinkedList?

@PositiveGuy 2016-11-15 04:10:25

I see that the list variable is set to type ArrayList. Why wouldn't it be like C# where you have List<int> someVar = new List<int>() ?

@Alston 2016-11-22 12:33:06

why should I change it into LinkedList?

@kgiannakakis 2016-11-22 13:05:48

@Alston: LinkedList is another List implementation that is better suited in some cases than ArrayList. See…

@Ungeheuer 2017-03-26 02:02:52

But why have ArrayList specific methods if you're just going to restrict its functionality anyways?

@Siamaster 2017-08-28 14:39:30

It's a bad practice that Java-developers has picked up. It makes no sense to lose concrete type information when you have just declared it. It's not hard to change the declaration and other assignments. And if I have to use functionality specific to ArrayList that List doesn't specify, I already have much more to worry about than changing the declaration and other assignments. It's only good for laziness when you are trying to measure the performance between different collection types. I wouldn't do that in production code if no one forced me.

@wzbozon 2013-12-05 17:14:10

When you write List, you actually tell, that your object implements List interface only, but you don't specify what class your object belongs to.

When you write ArrayList, you specify that your object class is a resizable-array.

So, the first version makes your code more flexible in future.

Look at Java docs:

Class ArrayList - Resizable-array implementation of the List interface.

Interface List - An ordered collection (also known as a sequence). The user of this interface has precise control over where in the list each element is inserted.

Array - container object that holds a fixed number of values of a single type.

@mazatwork 2013-04-21 12:20:37

I use (2) if code is the "owner" of the list. This is for example true for local-only variables. There is no reason to use the abstract type List instead of ArrayList. Another example to demonstrate ownership:

public class Test {

    // This object is the owner of strings, so use the concrete type.
    private final ArrayList<String> strings = new ArrayList<>();

    // This object uses the argument but doesn't own it, so use abstract type.
    public void addStrings(List<String> add) {

    // Here we return the list but we do not give ownership away, so use abstract type. This also allows to create optionally an unmodifiable list.
    public List<String> getStrings() {
        return Collections.unmodifiableList(strings);

    // Here we create a new list and give ownership to the caller. Use concrete type.
    public ArrayList<String> getStringsCopy() {
        return new ArrayList<>(strings);

@Populus 2015-01-30 18:22:57

What if you decide for some reason that a LinkedList is going to work better than an ArrayList, you'd have to change the signatures of the assessor methods, which also means thing using those methods will have to be reviewed and possibly refactored... which may chain all the way up to the highest level.

@ToolmakerSteve 2015-09-13 16:27:39

@Populus - you missed that getStrings returns a List, rather than ArrayList. Any caller which should be dealing with the member in an abstract way, will use that accessor.

@Populus 2015-09-14 15:03:19

@ToolmakerSteve I was referring to getStringsCopy() which creates a copy of strings. strings is an internal variable, so you can change it as much as you need to to cater to evolving requirements. But the interface (the public methods) should not change if you can help it. Returning an ArrayList locks the class to using an ArrayList implementation, when ArrayList is merely a List using arrays to implement the behaviour, so it has no added functionality over List at all.

@raudi 2016-11-14 10:30:15

I agree that it is usually not a good idea to have public methods receive or return concrete types like ArrayList. But @mazatwork also has a point with his "owner" definition. If the owner knows that the List has to be of a certain type then he has to insure that and therefore declare it. See also my answer about Serialization

@True Soft 2010-02-17 07:55:27

I think the people who use (2) don't know the Liskov substitution principle or the Dependency inversion principle. Or they really have to use ArrayList.

@Hans Westerbeek 2010-02-17 07:54:29

The only case that I am aware of where (2) can be better is when using GWT, because it reduces application footprint (not my idea, but the google web toolkit team says so). But for regular java running inside the JVM (1) is probably always better.

@Pavel Vyazankin 2010-02-17 07:51:38

(3) Collection myCollection = new ArrayList();

I am using this typically. And only if I need List methods, I will use List. Same with ArrayList. You always can switch to more "narrow" interface, but you can't switch to more "wide".

@Omar Kooheji 2014-05-12 19:54:55

Is this a thing people do? By this reasoning I should be using Object everywhere. I can think of very few designs that as vague enough to need to to use the Collection interface directly. I'm going to assume by the 8 upvotes that at least 7 other people do this...

@Subby 2014-08-16 12:27:04

@OmarKooheji That made me laugh :) But it's still a valid point!

@ToolmakerSteve 2015-09-13 16:25:24

I look forward to the day when our tools will examine which methods (members) are used, and tell us the narrowest declaration that includes those methods. BUT if we then attempt to use a method of wider scope, will tell us that we could use that method, if we changed the variable type.

@Pavel Molchanov 2018-08-01 20:29:14

If an application needs methods of the Collection interface only then it's an acceptable solution. And if an application uses methods of Object class only then Object o = <any object>; is an acceptable solution as well.

@extraneon 2010-02-17 07:47:58

I would say that 1 is preferred, unless

  • you are depending on the implementation of optional behavior* in ArrayList, in that case explicitly using ArrayList is more clear
  • You will be using the ArrayList in a method call which requires ArrayList, possibly for optional behavior or performance characteristics

My guess is that in 99% of the cases you can get by with List, which is preferred.

  • for instance removeAll, or add(null)

Related Questions

Sponsored Content

84 Answered Questions

[SOLVED] Is Java "pass-by-reference" or "pass-by-value"?

55 Answered Questions

[SOLVED] Creating a memory leak with Java

20 Answered Questions

15 Answered Questions

[SOLVED] How to clone or copy a list?

34 Answered Questions

[SOLVED] Create ArrayList from array

44 Answered Questions

[SOLVED] How to make a flat list out of list of lists

28 Answered Questions

[SOLVED] Finding the index of an item given a list containing it in Python

  • 2008-10-07 01:39:38
  • Eugene M
  • 3405303 View
  • 2805 Score
  • 28 Answer
  • Tags:   python list indexing

28 Answered Questions

[SOLVED] How do I check if a list is empty?

  • 2008-09-10 06:20:11
  • Ray Vega
  • 2415980 View
  • 3235 Score
  • 28 Answer
  • Tags:   python list

30 Answered Questions

[SOLVED] Initialization of an ArrayList in one line

31 Answered Questions

[SOLVED] When to use LinkedList over ArrayList in Java?

Sponsored Content