类型推断:泛型,"var"

Type inference: Generics, "var"

我认为 Java 编译器 (Java 11) 可以自行推断出实际的泛型类型,如果我给它足够的提示,例如当泛型类型是一个方法参数并且我提供实际类型的实例作为参数。

例如我有以下class:

public class Var<T>
{
    public T value;

    public Var(T value)
    {
        this.value = value;
    }
}

然后,我尝试了以下 3 次尝试,我希望它们都能编译:

//(1) Compilation error!
Var v = new Var(0);
++v.value;

//(2) Compilation error!
Var v = new Var<Integer>(0);
++v.value;

//(3) Compiles!
Var<Integer> v = new Var(0);
++v.value;

1) 我希望 (1) 能够编译,因为通过使用 Integer(或 int)参数,编译器知道实际类型可能就足够了。所以在 ++v.value; 中,我希望编译器知道变量是 Integer,但事实并非如此。它仍然认为它是 Object.

2) 增加了一些明确的信息。但是编译器还是不明白。

3) 按预期编译。

然后,我尝试使用 var 关键字进行类型推断:

//(4) Compilation error!
var v = new Var(0);
++v.value;

//(5) Compiles!
var v = new Var<Integer>(0);
++v.value;

4) 同样,我希望 (4) 能够编译,因为类型可以从参数中推断出来。

5)(更正我的语法后:)按预期编译。

问题:

您能否解释为什么此代码在情况 (1)、(2)、(4) 中失败?

有没有办法使 var 关键字类型推断与这样的 class 一起工作?

I would expect (1) to compile,

这是原始类型,类似于写作

Var<Object> v = new Var<Object>();

但对象不支持++

这是基于 class Var<T> 隐含的,它是 shorthand 对于 class Var<T extends Object> 所以如果你有一个原始类型,它假定类型 T extends.

Adds some explicit information. But still the compiler does not understand.

代码无法编译我建议在正确的地方添加信息。

Var<Integer> v = new Var<>();

Var<Integer> v = new Var<Integer>();

Is there a way to make the var keyword type inference work with such a class

var 只是一个 shorthand,如果代码没有它就不能工作,添加它也无济于事。

正确的语法是:

var v = new Var<Integer>(0);

new <Integer>Var(0) 是使用泛型构造函数的模糊语法(与泛型方法非常相似)。你有一个通用类型。

原始代码应该会生成大量原始类型的警告消息。