システムエンジニア兼IT講師の備忘録

技術やトレーニングテクニックなどを思いのままに発信していきます。

JDK10からは「var」が導入されるらしい

こんにちは!

Java SE 9 の新機能が云々などと言っているそばから、
なんとOpenJDK 10が2018年3月頃に公式リリースとなるとの情報が入ってきました。

現在は、テストフェーズに以降しているようで、
アーリーアクセス版もこちらからダウンロード可能です。
JDK 10 GA Release

OpenJDK 10からは各バージョンのリリース頻度を変更し、約6ヶ月ごとに新バージョンをリリースする方針であるようです。

OpenJDK 10のリアルタイムな情報や予定などはこちらからどうぞ。
JDK 10

さて、今回は上記で紹介したJDK 10を早速ダウンロードして使ってみたわけなんですが、
どうやら「var」なるキーワードが導入されているようです。

早速、jshellを使って試してみました。
jshellをご存じない方はこちらの記事をご覧ください。

bowtin.hatenablog.com

試してみた

java version "10-ea"だそうです。
f:id:bowtin:20180202154943p:plain

早速以下のコードを試してみます。

var sampleNumber = 10;
var sampleString = "Hello";

System.out.println(sampleNumber + sampleString);

f:id:bowtin:20180202155422p:plain
ほんとだ。イケる。

いわゆる型推論を行っているようです。

本当に大丈夫なの?

一般的に、varと言うとデータ型が不定であるため、バグや例外の温床になりがちな印象なのですが
一応安全策はいくつか取られているようです。

①初期化せずに宣言のみを行うことはできない

例えば、こんなコードはダメみたいです。

var x;

ちなみに、nullもダメでした。

var x = null;

②クラスのメンバ変数として利用することはできない

class Human{
    var name; //データ型が不定で推論できないため、不可
    var age; //データ型が不定で推論できないため、不可
}

③インタフェース型で受け取れない

こんなコードを良く見かけると思います。

List<String> sampleList = new ArrayList<String>();

これの左辺側をvarにしてしまうと、ArrayList型で受け取っていることになってます。

var sampleList = new ArrayList<String>();

例えば、この状態でsampleList変数へLinkedListオブジェクトを代入しようとすると…

sampleList = new LinkedList<String>();

f:id:bowtin:20180202161240p:plain
型が違うのでダメだぞ!と怒られます。

まあ、こんなコードは書かないと思うので大丈夫だとは思います。

④ラムダもダメ

例えば、Comparatorを使ってハッシュコード順に並べ替えるとしたらこうなると思います。 (ハッシュ順の並べ替えなんてやりませんが...)

Comparator c = (obj1, obj2) -> {return obj1.hashCode() - obj2.hashCode();};

これの左辺をvarにするとダメです。

var c = (obj1, obj2) -> {return obj1.hashCode() - obj2.hashCode();};

f:id:bowtin:20180202163031p:plain

まとめ

まとめると、Javaのvarは以下のようになります。

  • 右辺を見て型が決定できないものはダメ
  • ローカル変数じゃないとダメ
  • 可読性下がるよっていう公式注意書き付き
  • リファクタリングがやりづらくなるという公式注意書き付き

他言語のvarに比べると、自由度が低いと感じるかもしれませんが JavaScriptのように自由すぎるわけでもなく、Javaなりにいい具合の妥協ポイントを突いてきた感じです。

では今日はこの辺で!