.net column
.NET開発者のためのブログメディア

Javaのinstanceofを分かりやすく解説!|安全なJavaプログラミングをしよう

2020年09月28日
SE
Javaで、インスタンスのクラス型が違う場合はどうすればいいです。
PM
instanceofを使えばいいです。では、具体的にinstanceofの使い方や応用について解説しましょう。

Javaのinstanceofとは?


JavaはどんなクラスのインスタンスもObject型で扱える便利な言語です。ただし、あるObject型のインスタンスが実際は違うクラス型の場合もあります。そう言った時に型を調べるにはどうしたらよいのでしょうか。

その場合は、instanceofを使えば解決します。この記事ではinstanceofの使い方とその応用、具体的な使用例を紹介するので是非ご覧ください。

instanceofの簡単なサンプル

以下はinstanceofの簡単なサンプルです。

Object o = “”test””;

if (o instanceof String) {
System.out.println(o);
}

このJavaサンプルを実行すると、testと表示されます。oはObject型の変数ですが、その実体の””test””はString型の文字列です。そのためinstanceofでString型とtrue判定され、if文の処理が実行されたということになります。

変数がnullだった場合は?

もしinstanceofでチェックする変数が以下のようにnullだったら、どうなるのでしょうか?

String s = null;

if (s instanceof String) {
System.out.println(s);
}

このJavaサンプルを実行しても、何も表示されません。sはString型ですが、実体がnullのためinstanceofの判定はfalseとなるのです。

instanceofは親クラスもチェックできる

instanceofはインスタンスの型だけでなく、その型の親クラスをチェックすることもできます。以下のJavaサンプルをご覧ください。

Integer intVal = Integer.valueOf(3);
Short shortVal = Short.valueOf((short)5);
Float floatVal = Float.valueOf(8.0f);
Object[] ary = new Object[3];

ary[0] = intVal;
ary[1] = shortVal;
ary[2] = floatVal;

int sum = 0;
for (int i = 0; i < ary.length; i++) {
if (ary[i] instanceof Number) {
sum += ((Number)ary[i]).intValue();
}
}

System.out.println(“”sum is “”+sum);

親クラスをチェックすれば安全に処理ができる

上のJavaサンプルを解説します。まずInteger型・Short型・Float型のクラスのインスタンスを生成し、それらをObject型の配列aryに格納します。そしてaryの中身を順にinstansofで親クラスがNumber型かどうかチェックします。

Integer型・Short型・Float型の親クラスは全てNumber型なのでinstanceofの判定trueになります。そしてary型をNumber型にキャストし、Number型のinvValueメソッドをコールして戻り値をsumに加算します。

間違った型でキャストすると例外が発生する

このJavaサンプルの実行結果は””sum is 16″”になります。3とshort型の5とfloat型の8がint型として合計されたということです。もし仮にNumber型が親クラスではないインスタンスをNumber型でキャストすると、ClassCastExceptionが発生します。

instanceofのおかげで安全に処理ができているということです。

instanceofはインターフェイスの実装もチェックできる

instanceofは親クラスのチェックだけでなく、インターフェイスを実装しているかどうかもチェックできます。

以下のJavaサンプルをご覧ください。なお実行する時は先頭に「import java.io.*;」が必要です。

Integer intVal = Integer.valueOf(123);

if (intVal instanceof Serializable) {
try {
// バイト配列で書き込む
File file = new File(“”c:\\test\\serial_file””);
ObjectOutputStream ost = new ObjectOutputStream(new FileOutputStream(file));
ost.writeObject(intVal);
ost.close();
// バイト配列を読み込む
ObjectInputStream ist = new ObjectInputStream(new FileInputStream(file));
Object o = ist.readObject();
ist.close();
if (o instanceof Integer) {
System.out.println(“”serial value is “”+((Integer)o).intValue());
}
} catch (Exception e) {
e.printStackTrace();
}
}

instanceofはシリアライズ処理で役立つ

JavaにはSerializableというインターフェイスがあります。これを実装しているとインスタンスをファイルに書き込み、それを読み込んで復元できます。このサンプルはそれを行っています。それでは説明しましょう。

まずInteger型の値が123のインスタンスを生成しています。そしてそれがSerializableを実装しているかinstanceofで、チェックしています。実装していれば、ObjectOutputStreamでファイルにインスタンスを書き出します。これをシリアライズすると言います。

instanceofにより安全に処理できる

その後、ObjectInputStreamでObject型として読み込みます。これをデシリアライズと言います。そしてinstanceofでInteger型であるかどうかをチェックし、そうであればInteger型でキャストし、intValueメソッドで値を取得します。

実行結果は、

serial value is 123

となります。ClassCastExceptionを発生させないように、instanceofがこういったケースで役立つことがわかります。

instanceofの他の利用方法

instanceofの他の使用例を紹介します。以下のJavaサンプルをご覧ください。

Object[] ary = new Object[10];

for (int i = 0;i < ary.length; i++) {
if (i%2==0) {
ary[i] = “””” + i;
}
else
{
ary[i] = Integer.valueOf(i);
}
}

int sum = 0;
for (int i = 0; i < ary.length; i++) {
if (ary[i] instanceof String) {
sum += Integer.valueOf((String)ary[i]);
}
else if (ary[i] instanceof Integer) {
sum += ((Integer)ary[i]).intValue();
}
}

System.out.println(“”sum is “”+sum);

複数の型が混在していてもinstanceofで対応できる

上のJavaサンプルは色々な型が混在している場合にinstanceofで個別対処することを想定したものです。解説すると、まずObject型の配列aryにString型の数字とInteger型の数値を交互に入れています。i%2を2で割った余りを取得し、””””+iでint型を文字列に変換しています。

その後、配列aryを全部instanceofでチェックし、String型ならInteger.valueOfメソッドで数値に変換し、IntegerならintValueメソッドで値を取得します。

最後に値の合計を表示します。””sum is 45″”と表示されます。このようにinstanceofは複数の型が混在する時に便利に使えるのです。

SE
instanceofはとても便利ですね。
PM
複数の型が混在する時でも便利に使えます。

instanceofで安全なJavaプログラミングをしよう

instanceofの使い方について解説しましたが、ご理解できましたでしょうか。

instanceofを使用すれば間違ったキャストを行ってClassCastExceptionが発生する事態を避けることができます。安全なJavaプログラミングのために是非活用してください。


.NET分野でのキャリアアップをお考えの方は、現在募集中の求人情報をご覧ください。

また、直接のエントリーも受け付けております。

エントリー(応募フォーム)