ローカル変数時のvarを用いた型推論(2)
利用できないケース
ローカル変数時と特定しているように、リスト4のようなローカル変数以外であるクラス変数や定数としては利用できません。
public class BasicVar {
// クラス変数には利用できないため、以下のようなコードは記述できない
private var str0 = "Hello World";
public static var DEF_VALUE = 100;
}
また、利用できそうでできないケースもあります。例えば、リスト5のようにint型の配列を作りたい場合にも利用できません。
jshell> var arr = {1,2,3,4};
| エラー:
| ローカル変数arrの型を推論できません
| (配列初期化子には明示的なターゲット型が必要です)
| var arr = {1,2,3,4};
| ^------------------^
jshell> var arr = new int[]{1,2,3,4};
arr ==> int[4] { 1, 2, 3, 4 }
注意すべきケース
一方、利用することで間違いやすくなるケースや勘違いしやすいケースもあります。これらは、varを使わなくても同じなのですが、型がないことでコーディングする際に勘違いを生みやすい場合があるので、その一例を紹介します。
リスト6はint型同士で割り算をした場合の例です。int型同士の計算はintになるので、型が記述してあってもなくても、勘違いしない、問題ないという方もいるかもしれません。
ただし、JavaScriptなど型制限がゆるい言語の場合には、0.5という値になるケースが多いので、他の言語の文化に慣れている方にとっては非常に勘違いしやすいコードになります。
var num1 = 1; var num2 = 2;
var num3 = num1 / num2; // 値は0になる
if( num3 > 0 ) {
// 0.5を期待
}
else {
// 実際にはこちらが実行される
}
その他の変更API
Java 10で変更されたAPIを紹介します。
コレクションのコピーメソッドの追加
List/Map/Setクラスに対して、リスト7のようにコピーするためのcopyOfメソッドが追加されました。
このメソッドを使うことでコレクションの内容をコピーしなくてよい場合など、実際にコピーせずに参照を返すことができるメリットがあります。
var list1 = List.of(1,2,3);
var list2 = List.copyOf(list1);
var map1 = Map.of("key1","val2");
var map2 = Map.copyOf(map1);
var set1 = Set.of("key1","key2");
var set2 = Set.copyOf(set1);
copyOfメソッドで作成されたオブジェクトは、ofメソッドで作成されたオブジェクトと同様に変更はできません。
従って、リスト8のように変更可能なListオブジェクトを、copyOfメソッドを使ってコピーしても、追加時には例外が発生します。
jshell> var list = new ArrayList<Integer>(); list ==> [] jshell> var list1 = List.copyOf(list); list1 ==> [] jshell> list1.add(1); | java.lang.UnsupportedOperationException thrown | at ImmutableCollections.uoe (ImmutableCollections.java:71) | at ImmutableCollections$AbstractImmutableList.add (ImmutableCollections.java:77) | at (#34:1)
Optionalでのメソッド追加
引数無しのorElseThrow()メソッドが追加されました。これは、Optional.get()もしくは、引数を指定したorElseThrow()の代替となるためのメソッドです。
getという名称から多くの場合、例外を発生しないと勘違いしやすいということで別名のメソッドが用意されました。
Optional<String> opt = Optional.empty();
try {
// String str = opt.get(); と同じ
String str = opt.orElseThrow();
}
catch (NoSuchElementException ex){
// empty()の場合
}
