类型推断:泛型,“ var”

时间:2018-10-29 10:21:10

标签: java generics type-inference java-10

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

例如,我有以下课程:

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关键字类型推断与此类一起工作?

2 个答案:

答案 0 :(得分:7)

  

我希望(1)可以编译

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

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

但是对象不支持++

这是基于class Var<T>的缩写,它是class Var<T extends Object>的简写,因此,如果您使用的是原始类型,则假定类型T可以扩展。

  

添加一些显式信息。但是编译器仍然不理解。

代码未编译,我建议在正确的位置添加信息。

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

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

是否有一种方法可以使var关键字类型推断在此类中起作用

var只是一个简写,如果没有它,代码将无法工作,添加代码将无济于事。

答案 1 :(得分:2)

正确的语法为:

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

new <Integer>Var(0)是使用泛型构造函数的晦涩语法(与泛型方法几乎相同)。您有一个通用类型。

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