6

I am pretty new to Java and I wanted to know what this actually means:

List<Integer> list = new ArrayList<Integer>(); //Example 1

To distinguish this question from others, I've read the posts about polymorphism and the difference between Example 1 and Example 2, and I understand that Example 1 allows for "programming to interface." I also understand that with Example 1, list can easily be changed to LinkedList without affecting the rest of the code.

ArrayList<Integer> list = new ArrayList<Integer>(); //Example 2

But what I want to know what Example 1 actually means. Does it create a new List? Or does it create a new ArrayList? Does the resulting object have the properties of a List? Or does the resulting object have the properties of an ArrayList? Could I implement methods that an ArrayList uses on list without a compile error?

This is my first time posting a question, so please let me know if I can make any improvements.

Caroline Yi
  • 171
  • 1
  • 1
  • 6
  • First of all, ArrayList is the concrete implementation of List, exampl1 creates a new List of type ArrayList (concrete implementation). The variable "list" has the properties/methods of ArrayList. – imprezzeb Apr 18 '17 at 02:11
  • [Possibly A Duplicate](http://stackoverflow.com/questions/14903145/what-is-the-difference-between-list-and-arraylist) – thar45 Apr 18 '17 at 02:16
  • 1
    Possible duplicate of [Type List vs type ArrayList in Java](http://stackoverflow.com/questions/2279030/type-list-vs-type-arraylist-in-java) – ZhekaKozlov Apr 18 '17 at 02:17

6 Answers6

10

In both your examples, only the expression new creates instances of objects (the right hand side of the =), the left hand side only defines a variable that points to the object that you created.

In both cases, the object that you create is of type ArrayList.

List is an interface, not a class, and interfaces themselves cannot be instantiated. But ArrayList implements the interface List, so you can assign an instance of ArrayList to a variable of type List.

The advantage of Example 1 is that you can later decide to create another implementation of List (like LinkedList) and all your code that was using the List type for variables will still work without any change. While in Example 2, if you later decide that you need a different type of List, you need to change the type of all your variables that point to the actual object.

Your questions:

But what I want to know what Example 1 actually means. Does it create a new List? Or does it create a new ArrayList?

It creates a new ArrayList.

Does the resulting object have the properties of a List? Or does the resulting object have the properties of an ArrayList?

The resulting object has all the properties of an ArrayList.

However, through the variable list which as type List, you can only access the methods defined in the interfaces List.

But you can use type-casting to access the methods in ArrayList like this, if you later need to (but there is little reason as ArrayList doesn't have much beyond what's in List)

List<Integer> list = new ArrayList<Integer>(); //Example 1
ArrayList<Integer> arrayList = (ArrayList<Integer>) list; // type-cast
Erwin Bolwidt
  • 30,799
  • 15
  • 56
  • 79
  • 1
    Thank you for your answer! The mention of "type-casting" really clarified your answer and is exactly what I needed to hear. – Caroline Yi Apr 18 '17 at 02:27
1

As you might already know, List is an interface and ArrayList is a class. It means List is more generals whereas ArrayList is more specific.

In example 1, you are not able to invoke the additional methods supported by ArrayList e.g. you cannot invoke ensureCapacity because it is implemented inside Arraylist class.

Unlike example 2, you can invoke all functionalities that are supported by ArrayList. The benefit of using example 1 is to increase flexibility and minimize code changes in case the implementation changes, e.g. in future you decide to use LinkedList. You no need to worry about making any changes to all the lines where list variable has been used.

Fernando Tan
  • 634
  • 4
  • 14
1

Suppose you have a method that receives a List object as parameter.

public void myMethod(List<Integer> myList) { ... }

By using the example 1 you have the flexibility of passing different implementations of the List interface to this method without any type of casting.

List<Integer> list1 = new ArrayList<Integer>();
List<Integer> list2 = new LinkedList<Integer>();
myMethod(list1);
myMethod(list2);
alayor
  • 4,537
  • 6
  • 27
  • 47
0

Declaring a variable from its implemented interface is normally preferred, however depending on which interface or abstract class you use, you could lose access to some methods.

Basically, it allows your program to become more flexible.

Regarding your question:

Your first example declares a List and initializes it as an ArrayList. You will only be able to call methods from the List interface and its parent classes/interfaces.

Your second example declares an ArrayList and initializes it as an ArrayList, meaning you now have access to call methods in the ArrayList class, such as ArrayList#ensureCapacity or ArrayList#trimToSize.

Jacob G.
  • 28,856
  • 5
  • 62
  • 116
0

List is the interface and ArrayList is the concrete implementation of List interface.

If you are familiar with the concept of polymorphism, if not that ok refer to Java Interface (w3schools), or just remember that any class that implement an interface, have to override all of it's abstract methods so that class get all its method.

Your List variable will get add() method and these < > comparison braces is specifed as the "the of object that the list i going the add".

csalmhof
  • 1,820
  • 2
  • 15
  • 24
-1

It doesn't belong to java, It is belong to OOP:

Nothing actually happens to the object when you assign a reference to it to a variable of some super type or interface. You will only be able to invoke methods visible to that declared type on the variable.

And remember that any class implement an interface must implement all of it is methods

Fady Saad
  • 1,169
  • 8
  • 13