こんにちは!システムエンジニアのオオイシです。
Javaにはその変数は◯◯クラスのインスタンスか?を判定するときに便利なinstanceof演算子があります。この記事では
instanceof演算子の使い方を知りたい
データ型を判定する方法を教えて欲しい
というinstanceof演算子の基本的な解説から
- サブクラスがスーパークラスを継承しているかを判定する方法
- インターフェースを実装しているかを判定する方法
- instanceof演算子で左辺がnullの場合
についても解説していきます。今回はそんなinstanceof演算子の使い方についてわかりやすく解説します!
なお、Javaの記事については、こちらにまとめています。
instanceof演算子とは
instanceof演算子とは、
- ◯◯クラスのインスタンスか?
- ◯◯クラスのサブクラスのインスタンスか?
- ◯◯インターフェース実装したクラスのインスタンスか?
- ◯◯インターフェース実装したサブクラスのインスタンスか?
を判定します。instanceof演算子は次のように記述します。
書き方:
変数名 instanceof クラス名 変数名 instanceof インターフェース名
戻り値はtrueかfalseを返します。trueを返す条件は、
- 変数がinstanceofの右辺で指定したクラスのインスタンスである
- 変数がinstanceofの右辺で指定したインターフェースを実装したクラスのインスタンスである
の2点です。注意してほしいのは、instanceof演算子が使えるのは参照型の変数のみであるということです。つまり、int型やboolean型などのプリミティブ型には使えません。
使用した場合には、コンパイルエラーになります。なぜならばinstanceofの名前が表すとおり○○クラスのインスタンスか?を判定するための演算子だからです。プリミティブ型はインスタンスを作成できないためinstanceof演算子は使えないと覚えておいてください。
instanceof演算子の実践的な使い方としては、例えば、if文を使ってこの変数は○○クラスへダウンキャスト可能か?を判定するときなどに利用します。
ダウンキャストとは、サブクラスへ型変換することで、ダウンキャストができない場合には「java.lang.ClassCastException」という例外が発生します。
そのため、ダウンキャストができるかどうかを事前にチェックするときに使用します。キャストについては、こちらで詳しく説明していますので、ぜひ参考にしてください。
instanceof演算子の使い方
ここではサンプルコードを交えてinstanceof演算子の使い方を解説します。
データ型を判定する方法
instanceof演算子はその変数は◯◯クラスのインスタンスか?を判定するときに使用します。instanceof演算子を使用して、Object型の変数がStringクラスのインスタンスであるかを判定する方法を次のプログラムで確認しましょう。
public class Main { public static void main(String[] args) { Object obj = "samurai"; System.out.println(obj instanceof String); System.out.println(obj instanceof Integer); } }
実行結果:
true false
変数objはStringクラスのインスタンスですが、Integerクラスのインスタンスではないことが確認できました。もう1点、実践的な例としてStringクラスへダウンキャストが可能な場合はキャスト処理をするサンプルコードを紹介します。
public class Main { public static void main(String[] args) { Object obj = "samurai"; if (obj instanceof String) { String str = (String) obj; // Object型をString型へキャスト System.out.println("変数objの値は「" + str + "」です。"); } else { System.out.println("変数objはString以外の型です。"); } } }
実行結果:
変数objの値は「samurai」です。
このサンプルコードは、変数objの型が何なのかわからないので、String型にキャストできるかをinstanceof演算子で確認してからキャストしています。
サブクラスがスーパークラスを継承しているかを判定する方法
instanceof演算子を使って、サブクラスがスーパークラスを継承しているのかどうかを判定することができます。
instanceof演算子で指定するクラスが、サブクラスとスーパークラスどちらでもtrueが返ります。サンプルコードで確認してみましょう。
public class Main { public static void main(String[] args) { SubClass sub = new SubClass(); System.out.println(sub instanceof SubClass); System.out.println(sub instanceof SuperClass); } } class SuperClass {} class SubClass extends SuperClass{}
実行結果:
true true
このプログラムでは、変数subが指定したスーパークラスのサブクラスのインスタンスかどうかを判定しています。このようにして、サブクラスがスーパークラスを継承しているかを判定することができました。
なお、クラスの継承方法の詳細については、こちらの記事で詳しく解説しているので、ぜひ確認してみてください。
インターフェースを実装しているかを判定する方法
instanceof演算子を使って、インターフェースを実装しているのかどうかを判定することができます。
instanceof演算子を使うには次のように
変数名 instanceof インターフェース名
と記述しましょう。instanceof演算子を使って、インターフェースを実装しているのかどうかを判定する方法を、次のサンプルコードで確認してみましょう。
public class Main { public static void main(String[] args) { SubClass sub = new SubClass(); System.out.println(sub instanceof SubClass); System.out.println(sub instanceof Interface); } } interface Interface {} class SuperClass implements Interface {} class SubClass extends SuperClass {}
実行結果:
true true
このプログラムでは、変数subが指定したインターフェースを実装したクラスのインスタンスであるかどうかを判定しています。このようにして、インタフェースを実装しているのかどうかを判定することができました。
インターフェース詳細については、こちらの記事で詳しく解説しているので、ぜひ確認してみてください。
instanceof演算子で左辺がnullの場合
instanceof演算子の左辺がnullの場合はどのように判定されるでしょうか?nullを参照する変数はインスタンスを参照していないという状態です。そのため、instanceof演算子で左辺がnullの場合は、結果が常にfalseになります。
サンプルコードで確認してみましょう
public class Main { public static void main(String[] args) { String str = null; System.out.println(str instanceof Object); } }
実行結果:
false
このサンプルコードでは、null が Objectクラスのインスタンスであるかどうかを判定しています。Objectクラスは全てのクラスの親クラスであるため、instanceof演算子を使った場合に通常はすべてtrueを返します。ただし、左辺がnullの場合にはfalseを返します。
まとめ
いかかでしたか?
今回はinstanceof演算子の使い方について説明しました。instanceof演算子は、
- その変数は◯◯クラスのインスタンスか?
- その変数は◯◯インターフェースを実装したのインスタンスか?
を判定するために使用します。instanceof演算子は、インスタンス変数のクラスによって処理を切り替えたい場合に有効ですのでぜひ活用してみてください。
もし、instanceof演算子の使い方を忘れてしまったらこの記事を確認してください!