Javaの型判定でのinstanceof演算子について徹底解説!

- システム
エンジニア - Javaのinstanceofはどのように使うのでしょうか。
- プロジェクト
マネージャー - インスタンスが指定したクラスであるかどうかを判定してくれるキーワードです。そのクラスで合っているかどうかをチェックしてくれます。
Javaのinstanceofとは?
Javaのinstanceofは、インスタンスが指定したクラスであるかどうかを判定してくれるキーワードです。使い方は以下のように主にif文で利用します。
Object o = “”文字列です。””;
if (o instanceof String) {
System.out.println(“”oはString型です。””);
}
Javaの全てのクラスはObject型を親クラスに持つので、Object型として生成することができます。しかしObject型の参照変数でクラスを生成すると、実体は何のクラスかわからなくなります。そこでinstanceofで「このクラスじゃないの?」とチェックすれば良いというわけです。
instanceofは親クラスやインターフェイスもわかる
instanceofなら親クラスやインターフェイスもわかります。例えば以下を実行すると、
Number n = Integer.valueOf(100);
System.out.println(n instanceof Integer);
System.out.println(n instanceof Number);
System.out.println(n instanceof java.io.Serializable);
結果は、
true
true
true
になります。Integerクラスは親クラスがNumberクラスで、NumberクラスがインターフェイスのSerializableを実装しているからです。
対象がnullだった場合のinstanceofの挙動
instanceofの対象になる参照変数がnullだった場合はどうなるのでしょうか。
Number n = null;
System.out.println(n instanceof Number);
この結果は「false」になります。nullチェックをしなくてもNullPointerExceptionが出たりはしないということです。
instanceof以外のチェック方法 その1
なおObject型にはgetClass()というクラス名を取得するメソッドがあります。以下を実行すると、
Object o = “”文字列です。””;
System.out.println(o.getClass());
以下のように表示されます。
class java.lang.String
instanceofを使わずに、以下のようにクラスをチェックすることも可能です。
Object o = “”文字列です。””;
if (o.getClass().equals(String.class)) {
System.out.println(“”String型です。””);
}
ただしこの方法はinstanceofと違い、親クラスやインターフェイスと比較するとfalseになります。インスタンス自身のクラスだけしかチェックできないことに注意してください。
instanceof以外のチェック方法 その2
.class拡張子を使った以下のようなチェック方法もあります。
Object o = “”文字列です。””;
if (String.class.isInstance(o)) {
System.out.println(“”String型です。””);
}
このJavaサンプルはinstanceofを使った場合と全く同じ動作をします。上のequalsを使う方法と違って親クラスやインターフェイスにも対応できます。
型がわかったらキャストをする
instanceofでtrueと判断した場合は、以下のJavaサンプルのように()でキャストしてその型の参照変数に入れることができます。型チェックを行うことで、キャストできない時に発生するClassCastExceptionを防ぐことが出来ます。
Number n = Integer.valueOf(100);
if (n instanceof Integer) {
Integer i = (Integer)n;
}
class.isAssignableFromでキャストできるかどうかを判定
class.isAssignableFromを使うとクラスを指定してキャストできるかどうかを判定できます。
if (Number.class.isAssignableFrom(Integer.class)) {
System.out.println(“”Numberにキャストできます””);
}
if (java.io.Serializable.class.isAssignableFrom(Integer.class)) {
System.out.println(“”Serializableにキャストできます””);
}
これを実行すると以下のようにキャストできることがわかります。ただこれはプログラムをする前にわかっているべきことなので、使う機会は少ないかもしれません。
Numberにキャストできます
Serializableにキャストできます
instanceofの使用例
instanceofを使用する具体例を挙げましょう。一般的にはシリアライズ・デシリアライズの時に使うケースが多く見られます。
シリアライズとはインスタンスをファイルなどの実体のある形に変換することです。以下がシリアライズの例です。なおソースの先頭には「import java.io.*;」を追加してください。
Integer iObj = Integer.valueOf(12345);
File file = new File(“”c:\\test\\iObj””);
// シリアライズする
try (ObjectOutputStream oo = new ObjectOutputStream(new FileOutputStream(file));) {
oo.writeObject(iObj);
}
catch (Exception e) {
e.printStackTrace();
}
シリアライズでファイルに変換できる
上のJavaサンプルではInteger型のインスタンスを生成し、ファイルを開いてそのインスタンスを書き出しています。これがシリアライズです。なおtry()の中にファイル操作処理を記述すると、操作終了後に自動的にCloseしてくれます。
これを実行するとiObjというバイナリファイルが出来ます。テキストエディタで無理矢理開くと、java.lang.Integerなどの文字が見えるはずです。できればバイナリエディタの方が望ましいです。
デシリアライズでファイルを読み込む
次はデシリアライズをするJavaサンプルです。デシリアライズとはシリアライズ化したファイルを読み込んでインスタンスに戻すことです。上のサンプルソースに続けて記述します。
// デシリアライズする
Object readObj = null;
try(ObjectInputStream oi = new ObjectInputStream(new FileInputStream(file));) {
readObj = oi.readObject();
}
catch (Exception e) {
e.printStackTrace();
}
instanceofで読み込んだインスタンスをチェックする
上のJavaサンプルでreadObjというObject型の参照変数にデシリアライズをしました。しかしこのままではObject型なので使えません。そこでinstanceofを使うのです。
// Integer型であればキャストして値を取得
if (readObj instanceof Integer) {
Integer i = (Integer)readObj;
System.out.println(i.intValue());
}
シリアライズ処理にinstanceofは欠かせない
実行結果は以下になります。ファイルにシリアライズしたInteger型が復元できていることがわかります。
12345
シリアライズはクラスの情報を保持したまま保存できるので、とても使い易くて便利です。そしてデシリアライズで復元した時にはinstanceofによるチェックは必須です。是非シリアライズを活用してください。
- システム
エンジニア - Javaのinstanceofの使い方が理解できました。
- プロジェクト
マネージャー - シリアライズ処理でインスタンスを復元した時などの間違いを防ぐために、Javaのinstanceofの使い方をよく理解しておきましょう。
instanceofで安全なJavaプログラミングを実現
Javaのinstanceofを解説しましたが、ご理解頂けましたでしょうか。シリアライズ処理でインスタンスを復元した時などは必ずinstanceofでチェックすれば間違うことはありません。安全なJavaプログラミングにinstanceofは必須と言えます。
FEnetJava・Javaコラムは株式会社オープンアップシステムが運営しています。
株式会社オープンアップシステムはこんな会社です
秋葉原オフィスには株式会社オープンアップシステムをはじめグループのIT企業が集結!
数多くのエンジニアが集まります。

-
スマホアプリから業務系システムまで
スマホアプリから業務系システムまで開発案件多数。システムエンジニア・プログラマーとしての多彩なキャリアパスがあります。
-
充実した研修制度
毎年、IT技術のトレンドや社員の要望に合わせて、カリキュラムを刷新し展開しています。社内講師の丁寧なサポートを受けながら、自分のペースで学ぶことができます。
-
資格取得を応援
スキルアップしたい社員を応援するために資格取得一時金制度を設けています。受験料(実費)と合わせて資格レベルに合わせた最大10万円の一時金も支給しています。
-
東証プライム上場企業グループ
オープンアップシステムは東証プライム上場「株式会社オープンアップグループ」のグループ企業です。
安定した経営基盤とグループ間のスムーズな連携でコロナ禍でも安定した雇用を実現させています。
株式会社オープンアップシステムに興味を持った方へ
株式会社オープンアップシステムでは、開発系エンジニア・プログラマを募集しています。
年収をアップしたい!スキルアップしたい!大手の上流案件にチャレンジしたい!
まずは話だけでも聞いてみたい場合もOK。お気軽にご登録ください。


Java新着案件New Job
-
官公庁向け業務システム開発/Java/東京都千代田区/【WEB面談可】/テレワーク
月給39万~44万円東京都千代田区(永田町駅) -
販売管理システム開発/Java/東京都中央区/【WEB面談可】/テレワーク
月給49万~55万円東京都中央区(京橋駅) -
生命保険会社向けシステム開発/Java/東京都千代田区/【WEB面談可】/テレワーク
月給42万~48万円東京都千代田区(大手町駅) -
社会保険システムのパッケージ開発/Java/東京都港区/【WEB面談可】/テレワーク
月給42万~48万円東京都港区(新橋駅) -
金融機関向けシステム更改/Java/東京都江東区/【WEB面談可】/テレワーク
月給46万~51万円東京都江東区(豊洲駅) -
大手通信会社者向けWebシステム改修/Java/東京都港区/【WEB面談可】/テレワーク
月給42万~48万円東京都港区(品川駅)