是否将 var 与文字一起使用会导致基元或基元包装类



在阅读并谈论Java 10s之后,新的保留类型名称var (JEP 286:局部变量类型推断(,讨论中出现了一个问题。

当它与文字一起使用时,如下所示:

var number = 42;

number现在是int还是Integer?如果您只是将其与比较运算符一起使用或作为参数使用,则由于自动装箱和-unboxing,通常无关紧要。但由于Integer的成员功能,它可能很重要

那么var、基元int或类Integer创建哪种类型呢?

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

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

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

如果您需要将var作为盒装基元,您可以执行以下操作:

var x = (Integer) 10;  // x is now an Integer

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

如果 LocalVariableType var ,则让 T 成为初始值设定项表达式的类型,当它被视为未出现在赋值上下文中时,因此它是一个独立的表达式 (15.2(。局部变量的类型是 T 相对于 T (4.10.5( 提到的所有合成类型变量的向上投影

换句话说,局部变量的推断类型是初始值设定项表达式用作独立表达式时将具有的类型。 42作为独立表达式具有类型 int ,因此,变量 number 的类型为 int

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

让我们测试一下。使用 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( 以外的值。将缓存该范围内的整数实例。

编译器

处理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"

最新更新