Java 10s new reserved type namevar
( JEP 286:ローカル変数の型推論 )、ディスカッションで1つの質問が生じました。
次のようなリテラルで使用する場合:
var number = 42;
number
はint
またはInteger
になりましたか?比較演算子と一緒に、またはパラメーターとして使用するだけの場合は、オートボクシングと-unboxingのおかげで通常は問題になりません。しかし、Integer
sメンバー関数のため、それが問題になる可能性があります。
それでは、プリミティブ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
、ergoであるため、変数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
最初の比較では、2つの変数は同じではありません。それらは異なるインスタンスです。ただし、2番目の比較は真であるため、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"