Issue
Hi: this code get compiled:
public static void main( String[] args ) {
var list = new ArrayList<>();
list.add("hello world");
list.add(1);
list.add(1.01);
System.out.println(list);
System.out.println( "Hello World!" );
}
But with runtime issue. The list
local variable is of ArrayList
but not any ArrayList<xxx>
generic type. Why java let this kind of code pass compilation?
If I change the 1st line into:
ArrayList list = new ArrayList<>();
Then javac reports a warning of unchecked/unsafe operation, suggest to use -Xlint:unchecked
and re-compile. Why var
doesn't trigger any compilation error/warning here?
Thanks!
Solution
Usage of var
and the diamond operator together is legal in Java. There is no compiler rule that there must be a type to be inferred explicitly.
This runs without a compiler or runtime error, which you'd see by trying to run it yourself. Even if you add a Thread
to the list, then we can infer that Java infers Object
for the generic type of the ArrayList
. There are no common classes or common interfaces inferred, because Java won't consider subsequent statements.
You can also try to assign the returned value of a call to get
to say an Integer
, but the compiler will complain that it can't be converted to the type of your variable, unless you declare the variable to be Object
or var
.
Integer one = list.get(1); // Error, can't convert Object to Integer
Object o1 = list.get(1); // Compiles
var v1 = list.get(1); // Compiles, inferred type: Object
Answered By - rgettman
Answer Checked By - Candace Johnson (JavaFixing Volunteer)