代码之家  ›  专栏  ›  技术社区  ›  rapt

类型推断:泛型,“var”

  •  -1
  • rapt  · 技术社区  · 6 年前

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

    例如,我有以下课程:

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

    然后,我尝试以下三种尝试,我希望所有这些都能编译:

    //(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;
    

    Integer (或 int )参数,编译器就可以知道实际的类型。所以在 ++v.value; 我希望编译器知道变量是 ,但事实并非如此。它仍然认为这是一个 Object

    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)种情况下失败吗?

    关键字类型推断是否适用于这样的类?

    2 回复  |  直到 6 年前
        1
  •  8
  •   Peter Lawrey    6 年前

    我希望(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 只是一个简写,如果没有它代码就不能工作,添加它也没用。

        2
  •  2
  •   Tom Hawtin - tackline    6 年前

    正确的语法是:

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

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