/*1.*/ List l = new ArrayList<Number>();
/*2.*/ List<String> ls = l; // unchecked warning
/*3.*/ l.add(0, new Integer(42)); // another unchecked warning
/*4.*/ String s = ls.get(0);
If the lines 2 and 3 produce an unchecked warning then why doesn’t the 4th line generate a unchecked warning since compiler does not know what ‘ls’ is referring to (List<String> or List<Integer>).
(Note: edited from the OP’s original post to make the code display as presumably intended – notably include the type parameters for List<E> everywhere.)
The compiler thinks that
lswill genuinely refer to a list of strings – line 4 would be “safe” (in terms of type safety) if there hadn’t already been dangerous operations – namely line 2.With no other warnings involved, a
List<String>should always end referring to a list which only contains references to strings (or null). But if you’ve already broken type safety, all bets are off (other than that the VM will catch those type violations at execution time).The warning shows which lines are dangerous – in this case, places where you’re using a raw type, i.e. you’re saying, “Well, we’ve got a list here. I’ve no idea what’s in it though.”
Line 4 doesn’t refer to any variables of raw types – it only refers to calling
geton aList<String>, and assigning the return value to aStringvariable. If you think this should produce a warning, please show which section of the Java Language Specification suggests that a warning is appropriate – I think you’ll find it hard to do so.