After reading and talking about Java 10s new reserved type name var
(JEP 286: Local-Variable Type Inference), one question arose in the discussion.
在阅读和讨论Java 10s新保留类型名称var(JEP 286:局部变量类型推断)之后,讨论中出现了一个问题。
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 Integer
s member functions it could matter.
数字现在是int还是Integer?如果您只是将它与比较运算符一起使用或作为参数使用它通常无关紧要,这要归功于autoboxing和-unboxing。但由于整数成员函数,它可能很重要。
So which type is created by var
, a primitive int
or class Integer
?
那么var,原始int或类Integer创建了哪种类型?
4 个解决方案
#1
31
var
asks the compiler to infer the type of the variable from the type of the initializer, and the natural type of 42
is int
. So number
will be an int
. That is what the JLS example says:
var要求编译器根据初始化程序的类型推断变量的类型,自然类型42是int。所以数字将是一个int。这就是JLS示例所说的:
var a = 1; // a has type 'int'
And I would be surprised if it worked any other way, when I write something like this, I definitely expect a primitive.
如果它以任何其他方式工作,我会感到惊讶,当我写这样的东西时,我绝对期待一个原始的。
If you need a var
as boxed primitive, you could do:
如果你需要一个var作为盒装基元,你可以这样做:
var x = (Integer) 10; // x is now an Integer
#2
10
According to the proposed specification changes in 14.4.1 Local Variable Declarators and Types:
根据14.4.1局部变量声明符和类型中提出的规范更改:
If LocalVariableType is
var
, then let T be the type of the initializer expression when treated as if it did not appear in an assignment context, and were thus a standalone expression (15.2). The type of the local variable is the upward projection of T with respect to all synthetic type variables mentioned by T (4.10.5).如果LocalVariableType是var,那么让T作为初始化表达式的类型,当它被视为没有出现在赋值上下文中时,因此是一个独立的表达式(15.2)。局部变量的类型是T相对于T(4.10.5)提到的所有合成类型变量的向上投影。
In other words, the inferred type for the local variable is the type that the initializer expression would have if it were used as a standalone expression. 42
as a standalone expression has type int
, ergo, the variable number
is of type int
.
换句话说,局部变量的推断类型是初始化表达式在用作独立表达式时将具有的类型。 42作为独立表达式的类型为int,ergo,变量number的类型为int。
Upward projection is a term defined in the spec changes that doesn't apply to simple cases like this.
向上投影是规范更改中定义的术语,不适用于此类简单情况。
#3
7
Let's test it. With jshell:
我们来试试吧。使用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
In the first comparison, the two variables are not the same; they're different instances. The second comparison is however true, hence an int must've been infered here.
在第一次比较中,两个变量不一样;他们是不同的例子。然而,第二个比较是正确的,因此必须在这里使用int。
Note: To try it at home, use values outside <-128, 128). Integer instances in that range are cached.
注意:要在家中尝试,请使用<-128,128之外的值。缓存该范围内的整数实例。
#4
1
The compiler treats var number = 42;
similarly to int number = 42;
编译器处理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"
And auto-boxing when:
和自动装箱时:
public void method(Integer i) {
System.out.print("Integer method");
}
var n = 42; // a has type 'int'
method(n); // => "Integer method"
#1
31
var
asks the compiler to infer the type of the variable from the type of the initializer, and the natural type of 42
is int
. So number
will be an int
. That is what the JLS example says:
var要求编译器根据初始化程序的类型推断变量的类型,自然类型42是int。所以数字将是一个int。这就是JLS示例所说的:
var a = 1; // a has type 'int'
And I would be surprised if it worked any other way, when I write something like this, I definitely expect a primitive.
如果它以任何其他方式工作,我会感到惊讶,当我写这样的东西时,我绝对期待一个原始的。
If you need a var
as boxed primitive, you could do:
如果你需要一个var作为盒装基元,你可以这样做:
var x = (Integer) 10; // x is now an Integer
#2
10
According to the proposed specification changes in 14.4.1 Local Variable Declarators and Types:
根据14.4.1局部变量声明符和类型中提出的规范更改:
If LocalVariableType is
var
, then let T be the type of the initializer expression when treated as if it did not appear in an assignment context, and were thus a standalone expression (15.2). The type of the local variable is the upward projection of T with respect to all synthetic type variables mentioned by T (4.10.5).如果LocalVariableType是var,那么让T作为初始化表达式的类型,当它被视为没有出现在赋值上下文中时,因此是一个独立的表达式(15.2)。局部变量的类型是T相对于T(4.10.5)提到的所有合成类型变量的向上投影。
In other words, the inferred type for the local variable is the type that the initializer expression would have if it were used as a standalone expression. 42
as a standalone expression has type int
, ergo, the variable number
is of type int
.
换句话说,局部变量的推断类型是初始化表达式在用作独立表达式时将具有的类型。 42作为独立表达式的类型为int,ergo,变量number的类型为int。
Upward projection is a term defined in the spec changes that doesn't apply to simple cases like this.
向上投影是规范更改中定义的术语,不适用于此类简单情况。
#3
7
Let's test it. With jshell:
我们来试试吧。使用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
In the first comparison, the two variables are not the same; they're different instances. The second comparison is however true, hence an int must've been infered here.
在第一次比较中,两个变量不一样;他们是不同的例子。然而,第二个比较是正确的,因此必须在这里使用int。
Note: To try it at home, use values outside <-128, 128). Integer instances in that range are cached.
注意:要在家中尝试,请使用<-128,128之外的值。缓存该范围内的整数实例。
#4
1
The compiler treats var number = 42;
similarly to int number = 42;
编译器处理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"
And auto-boxing when:
和自动装箱时:
public void method(Integer i) {
System.out.print("Integer method");
}
var n = 42; // a has type 'int'
method(n); // => "Integer method"