我以为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
关键字类型推断与此类一起工作?
答案 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)
是使用泛型构造函数的晦涩语法(与泛型方法几乎相同)。您有一个通用类型。
原始代码应该会生成大量原始类型的警告消息。