Lolly
Lolly

Reputation: 36442

Collection with generics

I have a question about using generics with collections.

ArrayList<Integer> al=new ArrayList<Integer>();

We know that the above line means that ArrayList al is restricted to hold only integers. So the following line gives a compilation error:

al.add("wwww");

But I don't understand what the below line means,

ArrayList al=new ArrayList<Integer>();

Where we don't give ArrayList<Integer> at the left side while declaring. Now the following line doesn't give a compilation error:

al.add("wwww");

So if I declare like

ArrayList al=new ArrayList<Integer>();

that means a1 can accept any types?

What's the difference between those two declarations?

Upvotes: 5

Views: 279

Answers (6)

shambalaxx
shambalaxx

Reputation: 51

This kind of declaration is allowed for backward compability. So you can for example pass you generic list to the method from old-style library wich accepts only raw list:

List<Integer> list = new ArrayList<Integer>();
OldStyledClass.method(myArray);

where method is declared like:

public static void method(List list)...

In this case you have some special utility methods in java.util.Collections. So you can pass to this method protected list:

OldStyledClass.method(Collections.checkedList(myArray, Integer.class));

If method will try to put into your list object of some other type you will get ClassCastException immediatley.

Upvotes: 0

Ted Hopp
Ted Hopp

Reputation: 234857

With this code:

ArrayList al = new ArrayList<Integer>();
a1.add("www");

the compiler will generate a warning (which you should heed!) but the code will run without error. The problem comes on extracting data from a1. If you "know" that it contains Integer values, you can just do this:

Integer val = (Integer) a1.get(index);

But when you hit the "www" element you're going to get a ClassCastException. Generics are meant to move such errors to compile time instead of forcing the poor developer to track down how a String value ended up in that Integer array list.

Upvotes: 5

kosa
kosa

Reputation: 66667

Generics are implemented by type erasure: generic type information is present only at compile time, after which it is erased by the compiler. So, ArrayList al declaration let compiler accept any type. Here is java doc on this topic.

Upvotes: 0

shift66
shift66

Reputation: 11958

you should write like this ArrayList<Integer> al=new ArrayList<Integer>(); to avoid adding to your list objects with another types because you'll see the error compile time. Of course you can use ArrayList al=new ArrayList<Integer>(); but then you must be careful. In another words, always use the first one :D

Upvotes: 0

Peter Svensson
Peter Svensson

Reputation: 6173

The latter declaration is basicly the same as:

ArrayList<Object> al=new ArrayList<Object>();

thus accepting any Object. It should not be used, and it is possible to use so that Java is backward compatible (pre Java1.5).

Upvotes: 0

Tomasz Nurkiewicz
Tomasz Nurkiewicz

Reputation: 340973

The latter declaration (without generic type) is obsolete and deprecated. You shouldn't use it, it compiles only for backward compatibility. Modern IDEs will generate warning here.

Also note that Java only enforces generic types at compile time, so technically you can add incorrect type to a collection with some extra casts. That's why it is better to stay with generics all the time and do not bypass them.

Upvotes: 9

Related Questions