为什么java允许“var”声明泛型变量而不指定类型,导致运行时问题?

Tro*_*yvs -3 java generics warnings types var

你好:这段代码被编译:

    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!" );
    }
Run Code Online (Sandbox Code Playgroud)

但存在运行时问题。局部list变量属于ArrayList但不是任何ArrayList<xxx>泛型类型。为什么java会让这种代码通过编译呢?

如果我将第一行更改为:

ArrayList list = new ArrayList<>();
Run Code Online (Sandbox Code Playgroud)

然后javac报未检查/不安全操作警告,建议使用-Xlint:unchecked并重新编译。为什么var这里不触发任何编译错误/警告?

谢谢!

rge*_*man 7

在 Java 中,一起使用var和 菱形运算符是合法的。没有编译器规则要求必须显式推断出类型。

它运行时不会出现编译器或运行时错误,您可以通过尝试自己运行它来看到这一点。即使您将 a 添加Thread到列表中,我们也可以推断 Java 推断了Object的泛型类型ArrayList。没有推断出公共类或公共接口,因为 Java 不会考虑后续语句。

您还可以尝试将调用的返回值分配为getan Integer,但编译器会抱怨它无法转换为变量的类型,除非您将变量声明为Objector 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
Run Code Online (Sandbox Code Playgroud)