【Java】ListとかMapを初期化するとき、型って省略していいの?

2019年1月25日Java, 初心者向け

Javaの導入部分の勉強をちゃんとやってこなかったせいかも知れないですけど、最近些細なことが分からなかったり、「これじゃダメだよ~」って他人にダメ出ししたところが実はあってたりして、日々未熟さを感じます。

Listの初期化ってどうしてる?

Javaのソースを書いてると、無意識でこういうソースを書いてたんですけどね。

// 右の型を省略
List<String> hoge = new ArrayList<>();

見ての通り、やってることはStringのListをnewしてるだけなんですが、正直なところ、なんで右側はArrayListなのに左はListなのかとか、なんで右側の型は略しちゃってんのとか、わからないまま使ってたんですよ。

でも、ある人は馬鹿正直に下みたいなソースで書いていたんです。

// 省略しない
ArrayList<String> hoge = new ArrayList<String>();

もちろんどっちでもエラーは出ません。
なんとなく、省略できるけどちゃんとこうして書いてあげたほうが確実でいいんだろうなぁとは思ってたんですが、コードはやっぱり短いほうがいいです。

逆に、アンニュイすぎる人ならこんな書き方もできちゃったり。さすがにないか。

// 両方省略しちゃう
List hoge = new ArrayList();

さすがにこれには警告のメッセージがでます。リストにどんな型でもつっ込めるようになりますが、せめてそうしたいならObject型を入れてあげればいいし、こんな変数を初期化しないといけないようなシステムは、よく言われる「設計の段階から崩壊してる」ものなんじゃないだろうか。

「ダイヤモンド演算子」というらしい

そもそも、 new ArrayList<String>() と書いた場合の <String> には、「型引数」という意味があって、初期化するときにその型に特化したクラスが生成できるようになります。

さらに、 ArrayList<> と省略した場合の <> には「ダイヤモンド演算子(オペレータ)」という名前があるそう。
これは2011年にリリースされたJava7からの追加機能で、初期化して変数に代入するタイミングで、生成するクラスの型を推理してくれるという便利機能。

var型は使えるのか?

Java 10が2018年3月にリリースされ、その中で「var型」が使えるようになりました。

varはJavaScriptやC#なんかではおなじみの型推測ですが、これは配列を初期化するときの型にもできます。

var hoge = new ArrayList<String>();
// varは暗黙のString型

ただし、注意しないといけないのは「右側の型が明確である場合」のみということです。

// 右の型を省略
var hoge = new ArrayList<>();

上のように書いてしまうと、ArrayList<>はArrayList<Object>として認識されます。実際、コーディングするうえでこうした曖昧な型宣言は望ましくないです。やめたほうがいいでしょう。

結論

この書き方で正解だった。

// 右の型を省略
List<String> hoge = new ArrayList<>();