ArrayList<Integer> takes String

public class Main {
    public static void main(String[] args) {

        ArrayList<Integer> ar = new ArrayList<Integer>();
        List l = new ArrayList();
        l.add("a");
        l.add("b");
        ar.addAll(l);
        System.out.println(ar);
    }
}

Output: [a,b]

You can't directly add String to ArrayList<Integer> ar, but by using addAll() it is possible.

How can we add String to ArrayList whose type has already been specified as Integer? Can anyone highlight clear implementation details and the reason behind this?

Jon Skeet
people
quotationmark

But how can we add strings to arraylist whose type has already been specified as Integer?

Because of the way Java generics was designed for backwards compatibility, with type erasure and raw types, basically.

At execution time, there's no such things as an ArrayList<Integer> - there's just an ArrayList. You're using the raw type List, so the compiler isn't doing any of its normal checks, either at compile-time or adding execution-time casts.

The compiler does warn you that you're doing unsafe things though:

Note: Main.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.

... and when you recompile with the relevant flag, it will warn about everything, including probably the most surprising line:

ar.addAll(l);

That's the one that surprises me somewhat, in terms of compiling - I believe it's effectively trusting that the List is a Collection<? extends Integer> really, when we know it's not.

If you avoid using raw types, this sort of mess goes away.

people

See more on this question at Stackoverflow