/*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 ls
will 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 get
on a List<String>
, and assigning the return value to a String
variable. 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.
Line 4 produces no compile-time warning because the type of ls
is List<String>
which means its get
methods returns a String
or null
. Any violation will be caught at compile time and will result in a ClassCastException
.
EDIT:
There are a number of things that the compiler knows about that the bytecode verifier and interpreter do not.
The java compiler knows about these things and so points out errors in their use, but the bytecode verifier and interpreter do not so it "erases" them when producing the portion of the .class
file meant for the interpreter.
So the steps in compilation are
.java
and .class
files..class
on its input CLASSPATH)..class
files.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With