36

After reading and talking about Java 10s new reserved type name var (JEP 286: Local-Variable Type Inference), one question arose in the discussion.

When using it with literals like:

var number = 42;

is number now an int or an Integer? If you just use it with comparison operators or as a parameter it usually doesn't matter thanks to autoboxing and -unboxing. But due to Integers member functions it could matter.

So which type is created by var, a primitive int or class Integer?

4

4 回答 4

34

var要求编译器从初始化器的类型推断变量的类型,自然类型为42is int。所以number将是一个int. 这就是JLS 示例所说的:

var a = 1;  // a has type 'int' 

如果它以任何其他方式起作用,我会感到惊讶,当我写这样的东西时,我绝对期待一个原始的。

如果你需要一个var盒装原语,你可以这样做:

var x = (Integer) 10;  // x is now an Integer
于 2018-03-22T09:03:42.207 回答
12

根据14.4.1局部变量声明器和类型中提议的规范更改

如果LocalVariableType是,那么当 T 被视为没有出现在赋值上下文中时,varT成为初始化表达式的类型,因此是一个独立的表达式( 15.2)。局部变量的类型是T相对于T (4.10.5) 提到的所有合成类型变量的向上投影。

换句话说,局部变量的推断类型是初始化表达式在用作独立表达式时所具有的类型。42由于独立表达式具有类型int,因此,变量number的类型为int

向上投影是规范更改中定义的术语,不适用于像这样的简单情况。

于 2018-03-22T13:06:19.033 回答
7

让我们测试一下。使用 jshell:

jshell> Integer boxed1 = 42000;
boxed1 ==> 42000

jshell> Integer boxed2 = 42000;
boxed2 ==> 42000

jshell> System.out.println(boxed1 == boxed2);
false

jshell> var infered1 = 42000;
infered1 ==> 42000

jshell> var infered2 = 42000;
infered2 ==> 42000

jshell> System.out.println(infered1 == infered2);
true

第一次比较,两个变量不一样;它们是不同的实例。然而,第二个比较是正确的,因此这里必须推断出一个 int 。

注意:要在家尝试,请使用 <-128, 128) 之外的值。该范围内的整数实例被缓存。

于 2018-03-22T09:36:06.323 回答
1

编译器var number = 42;类似地对待int number = 42;

public void method(Integer i) {
    System.out.print("Integer method");
}
public void method(int i) {
    System.out.print("int method");
}

var n = 42; // n has type 'int' 
method(n); // => "int method"

并在以下情况下自动装箱:

public void method(Integer i) {
    System.out.print("Integer method");
}

var n = 42; // a has type 'int'
method(n); // => "Integer method"
于 2018-04-16T09:08:15.803 回答