開発者ドキュメント

Java 10 LocalVariable型推論

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]にあります。




モバイルバージョンを終了