Skip to content
Advertisement

Initializing variables in Java as instances of different classes but same initializing keyword

I am new to Java and I finally faced with a problem that I have been postponing for a long time.

I was learning LinkedLists in Java and have the following confusion, please check:

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

public class LinkedListDemo {
    public static void main(String[] args) {
        List<Integer> myList = new LinkedList<Integer>();

        myList.add(1);
        myList.add(22);
        myList.add(42);

        Iterator it = myList.iterator();

        while(it.hasNext()){
            if((int)(it.next()) == 42)
                System.out.println("We found 42");
        }

        myList.remove();
        System.out.println(myList);
    }
}

Here myList.remove(); gives the following error : “cannot resolve the method ‘remove’.”

however, if I instantiate myList variable like this

LinkedList<Integer> myList = new LinkedList<Integer>();

I don’t have the same error and my code compiles successfully.

I just want to know the working behind this. I mean sometimes I declare ArrayList variables with

List myList = new ArrayList<>();

should I instead declare like this?

ArrayList myList = new ArrayList<>();

thank you

Advertisement

Answer

Separate abstraction from implementation

Separate abstraction from implementation allows to code thinking in “I know I’ll need here and there a List, but I still don’t know/want to choose which kind of List at this moment” or: “I’d like to keep my options open to any List implementation here and there in my code”. This is good thing to ease coding.

LinkedList and ArrayList are less abstract than List, which means that these are different implementations of List. Usually you will prefer to use more abstract classes, like List on this case, to separate abstraction from implementation, which is usually a good thing, e.g. to play with different implementations without changing the rest of your code. So:

List<Integer> myCoolList = new LinkedList<Integer>()

is usually better (as it promotes separation between abstraction and implementation, which is a good habit for your code) than:

LinkedList<Integer> myCoolList = new LinkedList<Integer>()

Now, if you choose to separate abstraction from implementation, of course you will lose the power to use methods specific for each implementation. But usually the most general class (in this case, List) will give enough alternatives to replace the lost methods ( the LinkedList.remove() method in this case)

User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement