1.概要
JDK 10で最も目に見える機能強化の1つは、初期化子を使ったローカル変数の型推論です。
このチュートリアルでは、この機能の詳細と例を示します。
2.はじめに
Java 9までは、ローカル変数の型を明示的に記述し、それが初期化に使用されたイニシャライザと互換性があることを確認する必要がありました。
String message = "Good bye, Java 9";
Java 10では、これがローカル変数を宣言する方法です。
@Test
public void whenVarInitWithString__thenGetStringTypeVar() {
var message = "Hello, Java 10";
assertTrue(message instanceof String);
}
-
message
のデータ型は提供していません。代わりに、メッセージを
varとしてマークし、コンパイラは右側にある初期化子の型から
message
__の型を推測します。
上記の例では、
__ message
のタイプは
String__になります。
-
この機能は、初期化指定子を持つローカル変数に対してのみ利用可能です。
** メンバ変数、メソッドパラメータ、戻り値の型などには使用できません。初期化子は、どのコンパイラが型を推論できないかに関係なく必要です。
この機能強化は、定型コードを減らすのに役立ちます。例えば:
Map<Integer, String> map = new HashMap<>();
これは次のように書き直すことができます。
var idToNameMap = new HashMap<Integer, String>();
これは、変数タイプではなく変数名に焦点を合わせるのにも役立ちます。
注意すべきもう1つのことは、**
__ var
はキーワードではないということです – これは、関数または変数名として
var
sayを使用するプログラムとの下位互換性を保証します。
var
は
int__と同じように予約済みの型名です。
最後に、
__
varを使用しても実行時のオーバーヘッドはないことに注意してください。
変数の型はまだコンパイル時に推測され、後で変更することはできません。
3.
var
の不正使用
前述のように、
__
varは初期化子なしでは動作しません。
var n;//error: cannot use 'var' on variable without initializer
null
で初期化してもうまくいきません。
var emptyList = null;//error: variable initializer is 'null'
非ローカル変数に対してはうまくいきません。
public var = "hello";//error: 'var' is not allowed here
ラムダ式は明示的なターゲット型を必要とするため、
__ var
__は使用できません。
var p = (String s) -> s.length() > 10;//error: lambda expression needs an explicit target-type
配列初期化子の場合も同様です。
var arr = { 1, 2, 3 };//error: array initializer needs an explicit target-type
4
var
を使用するためのガイドライン
__var
__を合法的に使用することができる状況がありますが、そうすることはお勧めできません。
たとえば、コードが読みにくくなる可能性がある状況では、
var result = obj.prcoess();
ここでは、
var
を合法的に使用していますが、
__ process()
__によって返される型を理解するのが難しくなり、コードが読みにくくなります。
java.net
には、http://openjdk.java.net/projects/amber/LVTIstyle.html[Javaにおけるローカル変数型推論のためのスタイルガイドライン]に関する記事があります。この機能を使用しながら、どのように判断を下すべきかについて。
長いパイプラインを持つストリームでは、
__var
__を避けるのが最善の方法です。
var x = emp.getProjects.stream()
.findFirst()
.map(String::length)
.orElse(0);
__var
__mayを使用しても予期しない結果が生じる可能性があります。
たとえば、Java 7で導入されたダイヤモンド演算子と一緒に使用すると、
var empList = new ArrayList<>();
__empList
の型は、
List <Object>
ではなく
ArrayList <Object>
になります。それを
ArrayList <従業員> __にしたい場合は、明示的に指定する必要があります。
var empList = new ArrayList<Employee>();
-
__var
__を指示不可能な型で使用すると予期しないエラーが発生する可能性があります
たとえば、匿名クラスのインスタンスで
__var
__を使用すると、次のようになります。
@Test
public void whenVarInitWithAnonymous__thenGetAnonymousType() {
var obj = new Object() {};
assertFalse(obj.getClass().equals(Object.class));
}
さて、別の
__Object
to
obj__を代入しようとすると、コンパイルエラーになります。
obj = new Object();//error: Object cannot be converted to <anonymous Object>
これは、
__objの推定型が
Object__ではないためです。
5.まとめ
この記事では、新しいJava 10ローカル変数型推論機能と例を紹介しました。
いつものように、コードスニペットはhttps://github.com/eugenp/tutorials/tree/master/core-java-10[over on GitHub]にあります。
次
”