S-JIS[2020-03-21/2021-03-21] 変更履歴

パターンマッチングinstanceof(Java14〜15)

Java14のinstanceofのパターンマッチング(プレビュー版)について。


概要

2020/3/17にリリースされたJava14で、プレビュー版としてinstanceofでパターンマッチングが使えるようになった。
Java15でSecond Previewになったが、内容に変更は無いらしい。[2021-03-21]

instanceofで型をチェックするのと同時に、その型の変数を定義できる。

	if (値 instanceof 型 変数) {
		// 変数がその型として使える
	}
パターンマッチングの例 従来のコーディング
if (obj instanceof String s) {
  // sがStringとして使える
}
if (obj instanceof String) {
  String s = (String)obj;
  〜
}

instanceofのパターンマッチングはJava14〜15ではプレビュー版の機能なので、この機能を使いたい場合はコンパイル時にjavacコマンドに--enable-previewを付ける必要があり、
また、実行時にjavaコマンドに--enable-previewを付ける必要がある。
JShellで試す場合もjshellコマンドに--enable-previewを付ける。

> javac --enable-preview --release 14 Example.java
> java --enable-preview Example

パターンマッチングの例

パターンマッチングの例 従来のコーディング 備考
Object obj = 〜;
if (obj instanceof String s) {

  System.out.println(s.length());
}
Object obj = 〜;
if (obj instanceof String) {
  String s = (String)obj;
  System.out.println(s.length());
}
instanceofでマッチした場合の変数が直接定義できる。
(objがnullの場合はそもそもinstanceofはfalseなのでマッチしない)
Object obj = 〜;
if (obj instanceof String s) {
  System.out.println(s);
  s = "abc"; ←エラー
  System.out.println(s);
}
  instanceofで定義した変数は再代入できない。(final扱い)[2021-03-21]
(正式版では代入可能)
String s = 〜;
if (s instanceof Object obj) {
}
  常に真となるクラスでも指定することも出来る。[2021-03-21]
(正式版ではコンパイルエラーになる)
if (obj instanceof String s) {
  System.out.println(s.length());
} else {
  System.out.println(s); ←エラー
}
  else部では変数は使用できない。
var s = 123;
if (obj instanceof String s) {
  System.out.println(s.length());
} else {
  System.out.println(s);
}
  if文の前で同名の変数を定義していた場合、
then部ではinstanceofで定義した変数となるが
else部では外側で定義されていた変数がそのまま使用できる。
まぎらわしいので、こういう使い方はやめた方が良さそう。
if (!(obj instanceof String s)) {
  System.out.println(obj.getClass());
} else {

  System.out.println(s.length());
}
if (!(obj instanceof String)) {
  System.out.println(obj.getClass());
} else {
  String s = (String)obj;
  System.out.println(s.length());
}
ifの条件式を否定にした場合は、else部で変数を使用できる。
(then部では変数を使用できない)
if (obj instanceof String s && !s.isEmpty()) {

  System.out.println(s.length());
}
if (obj instanceof String && !((String)obj).isEmpty()) {
  String s = (String)obj;
  System.out.println(s.length());
}
&&を使って、マッチした変数を後ろで使うことが出来る。
return (obj instanceof String s) && !s.isEmpty(); return (obj instanceof String) && !((String)obj).isEmpty();
var len = (obj instanceof String s) ? s.length() : 0; var len = (obj instanceof String) ? ((String)obj).length() : 0; 条件演算子(三項演算子)でもinstanceofのパターンマッチングが使える。
var s = -1;
var len = (obj instanceof String s) ? s.length() : s;
 

プレビュー機能へ戻る / Java目次へ戻る / 新機能へ戻る / 技術メモへ戻る
メールの送信先:ひしだま