
Java道|instanceofの使い方と型判定のしくみ
見た目は同じ配列の中でも、実体の型までは同じとは限りません。
instanceof を理解すると、オブジェクトの正体を見分けながら、安全に処理を分けられるようになります。
抽象クラスを使うと、共通の親クラスの型で、いろいろなサブクラスのオブジェクトをまとめて扱えるようになります。
たとえば、鬼滅の刃風にたとえると、Slayer という共通の剣士型を用意して、その配列の中に WaterSlayer や MedicalSlayer のような具体的な剣士オブジェクトを入れられます。
これはとても便利です。
共通の型でまとめられるので、同じ配列で管理でき、共通メソッドも同じ形で呼び出せます。
ただし、まとめて扱っていると、次のような場面も出てきます。
| 確認したいこと | 例 |
|---|---|
| この剣士は水の剣士なのか | WaterSlayer かどうか |
| この剣士は支援剣士なのか | MedicalSlayer かどうか |
| 特定のクラスだけに処理したい | WaterSlayer だけに特別訓練を行う |
このようなときに使うのが instanceof 演算子です。
instanceof を使うと、変数が指しているオブジェクトが、特定のクラスのものかどうかを true または false で判定できます。
つまり instanceof は、
オブジェクトの型を判定するための道具
です。
鬼滅の刃風にたとえると、instanceof は、隊士名簿に並んでいる剣士に対して、
「あなたは WaterSlayer クラスの剣士ですか」
と確認するようなものです。
instanceof は何をする演算子なのか
instanceof は、左側の変数が指しているオブジェクトが、右側のクラスのものかどうかを調べる演算子です。
基本の形は次のようになります。
object instanceof ClassNameたとえば、次のように書けます。
slayers[i] instanceof WaterSlayerこれは、slayers[i] が指しているオブジェクトが WaterSlayer クラスのものなら true、そうでなければ false になります。
| 式 | 意味 |
|---|---|
| slayers[i] instanceof WaterSlayer | slayers[i] の実体が WaterSlayer かどうか調べる |
| slayers[i] instanceof MedicalSlayer | slayers[i] の実体が MedicalSlayer かどうか調べる |
ここで大切なのは、instanceof は変数の宣言型だけを見るのではなく、実際に指しているオブジェクトの型を見て判定するという点です。
鬼滅の刃風にたとえると、名簿上は Slayer として並んでいても、本人確認をすれば WaterSlayer なのか MedicalSlayer なのかを判定できる、ということです。
↓クリックすると拡大表示されます。

なぜ instanceof が必要になるのか
抽象クラスやスーパークラスを使うと、複数の種類のオブジェクトをまとめて扱えます。
たとえば、次のような配列を考えます。
Slayer[] slayers;この配列には、Slayer を継承したサブクラスのオブジェクトを入れられます。
| 配列に入れる実体 | 説明 |
|---|---|
| WaterSlayer | 水の剣士 |
| MedicalSlayer | 支援剣士 |
配列の型だけを見ると、どちらも Slayer として扱われます。
しかし、実際の中身は WaterSlayer だったり、MedicalSlayer だったりします。
このとき、特定のサブクラスだけを見分けたいことがあります。
たとえば、WaterSlayer だけに水の呼吸の追加訓練を行いたい場合です。
また、MedicalSlayer だけに治療技術の確認をさせたい場合もあります。
こうしたときに instanceof を使うと、まとめて扱っているオブジェクトの中から、特定の型だけを判定できます。
つまり instanceof は、
多態性でまとめたオブジェクトを、必要に応じて見分けるための演算子
です。
鬼滅の刃風に考える instanceof の感覚
鬼滅の刃風にたとえると、instanceof は、隊士に対して、
あなたは本当にこの型の剣士ですか
と確認する札のようなものです。
たとえば、Slayer[] 配列に次のような剣士が入っているとします。
| 配列要素 | 実体 |
|---|---|
| slayers[0] | WaterSlayer |
| slayers[1] | MedicalSlayer |
このとき、次の判定を行います。
slayers[i] instanceof WaterSlayerすると、WaterSlayer の実体なら true です。
MedicalSlayer の実体なら false です。
| 実体 | slayers[i] instanceof WaterSlayer |
|---|---|
| WaterSlayer | true |
| MedicalSlayer | false |
これは、全員を Slayer としてまとめて扱いながら、必要なときだけ特定の剣士型を見分けるためのしくみです。
instanceof の動きを確認する
ファイル名:Sample2.java
abstract class Slayer
{
protected int speed;
public void setSpeed(int s)
{
speed = s;
System.out.println("速度を" + speed + "にしました。");
}
abstract void show();
}
class WaterSlayer extends Slayer
{
private String name;
private String breathingStyle;
public WaterSlayer(String n, String bs)
{
name = n;
breathingStyle = bs;
System.out.println(name + " 水の呼吸「" + breathingStyle + "」の剣士を作成しました。");
}
public void show()
{
System.out.println("水の剣士の名前は" + name + "です。");
System.out.println("呼吸の型は" + breathingStyle + "です。");
System.out.println("速度は" + speed + "です。");
}
}
class MedicalSlayer extends Slayer
{
private String name;
private String healingSkill;
public MedicalSlayer(String n, String hs)
{
name = n;
healingSkill = hs;
System.out.println(name + " 治療技術「" + healingSkill + "」の支援剣士を作成しました。");
}
public void show()
{
System.out.println("支援剣士の名前は" + name + "です。");
System.out.println("治療技術は" + healingSkill + "です。");
System.out.println("速度は" + speed + "です。");
}
}
class Sample2
{
public static void main(String[] args)
{
Slayer[] slayers;
slayers = new Slayer[2];
slayers[0] = new WaterSlayer("水月", "水流斬り");
slayers[1] = new MedicalSlayer("胡蝶香", "藤花治療");
for(int i = 0; i < slayers.length; i++){
if(slayers[i] instanceof WaterSlayer)
System.out.println((i + 1)
+ "番目のオブジェクトはWaterSlayerクラスです。");
else
System.out.println((i + 1)
+ "番目のオブジェクトはWaterSlayerクラスではありません。");
}
}
}実行結果
水月 水の呼吸「水流斬り」の剣士を作成しました。
胡蝶香 治療技術「藤花治療」の支援剣士を作成しました。
1番目のオブジェクトはWaterSlayerクラスです。
2番目のオブジェクトはWaterSlayerクラスではありません。Sample2.java の中心になる部分
このプログラムでは、まず抽象クラス Slayer を用意しています。
abstract class SlayerSlayer は抽象クラスなので、直接 new Slayer() のようにオブジェクトを作ることはできません。
しかし、Slayer 型の配列を作ることはできます。
Slayer[] slayers;
slayers = new Slayer[2];そして、その配列には Slayer を継承した具体的なサブクラスのオブジェクトを入れられます。
slayers[0] = new WaterSlayer("水月", "水流斬り");
slayers[1] = new MedicalSlayer("胡蝶香", "藤花治療");配列の中身を整理すると、次のようになります。
| 配列の位置 | 変数としての型 | 実際に入っているオブジェクト |
|---|---|---|
| slayers[0] | Slayer | WaterSlayer |
| slayers[1] | Slayer | MedicalSlayer |
見た目の型はどちらも Slayer です。
しかし、実体は WaterSlayer と MedicalSlayer で異なります。
そこで、ループの中で instanceof を使って、WaterSlayer かどうかを判定しています。
slayers[i] instanceof WaterSlayerこの式が true なら WaterSlayer、false なら WaterSlayer ではない、という判断ができます。
true と false はどう決まるのか
このプログラムでは、slayers[0] には WaterSlayer オブジェクトが入っています。
そのため、次の判定は true になります。
slayers[0] instanceof WaterSlayer一方、slayers[1] には MedicalSlayer オブジェクトが入っています。
そのため、次の判定は false になります。
slayers[1] instanceof WaterSlayer表で整理すると、次のようになります。
| 判定する式 | 結果 | 理由 |
|---|---|---|
| slayers[0] instanceof WaterSlayer | true | 実体が WaterSlayer だから |
| slayers[1] instanceof WaterSlayer | false | 実体が MedicalSlayer だから |
ここで大切なのは、slayers[0] も slayers[1] も、配列上は Slayer 型として扱われていることです。
しかし instanceof は、変数の宣言型ではなく、実体のクラスを見て判定します。
鬼滅の刃風にたとえると、隊士名簿には全員 Slayer として並んでいても、実際に札を確認すると、水の剣士なのか支援剣士なのかを見分けられるということです。
なぜ変数の型ではなく実体で判定するのか
ここは多態性と深くつながるポイントです。
多態性では、スーパークラス型や抽象クラス型の変数で、サブクラスのオブジェクトを扱えます。
たとえば、今回の配列では次のようになっています。
| 配列要素 | 見た目の型 | 実体 |
|---|---|---|
| slayers[0] | Slayer | WaterSlayer |
| slayers[1] | Slayer | MedicalSlayer |
このように、見た目の型と実体のクラスが違うことがあります。
instanceof は、この実体を見て判定します。
だから、Slayer 型の配列でまとめていても、その中から WaterSlayer だけを見つけることができます。
これは、多態性でまとめて扱う便利さを保ちながら、必要なときだけ個別の型を確認できるということです。
instanceof が便利な場面
instanceof は、特定のクラスのオブジェクトにだけ処理をしたいときに便利です。
たとえば、鬼滅の刃風に考えると、次のような場面です。
| 場面 | instanceof の使い方 |
|---|---|
| 水の剣士だけに特別訓練を行う | WaterSlayer かどうか判定する |
| 支援剣士だけに治療準備をさせる | MedicalSlayer かどうか判定する |
| 特定クラスだけ別メッセージを出す | if 文で処理を分ける |
| 配列の中身の型を確認する | ループ中に instanceof で調べる |
つまり instanceof は、
まとめて扱う便利さを保ちながら、必要なときだけ型によって処理を分けるための道具
です。
抽象クラスと instanceof は相性がよい
抽象クラスを使うと、サブクラスのオブジェクトを共通の型でまとめられます。
今回なら、WaterSlayer と MedicalSlayer を Slayer[] 配列でまとめています。
| 抽象クラスを使う利点 | 内容 |
|---|---|
| 共通メソッドを同じ形で呼べる | show() や setSpeed() など |
| 複数のサブクラスを1つの配列で管理できる | Slayer[] にまとめられる |
| 多態性を使える | 実体ごとにメソッドの動きが変わる |
一方で、まとめて扱っている中から「このクラスだけを見分けたい」という場面もあります。
そこで instanceof が役立ちます。
鬼滅の刃風にたとえると、まずは全員を Slayer として整列させます。
そのうえで、必要な場面だけ「水の剣士は誰か」を見分けるような使い方です。
instanceof と getClass() の違い
instanceof は、前に学んだ getClass() と少し似ています。
どちらもオブジェクトの型に関係するからです。
ただし、役割は違います。
| しくみ | 役割 | 向いている場面 |
|---|---|---|
| instanceof | 特定のクラスかどうかを true または false で判定する | if 文で処理を分けたいとき |
| getClass() | そのオブジェクトのクラス情報そのものを取り出す | 実体のクラス情報を確認したいとき |
instanceof は、
このオブジェクトは WaterSlayer ですか
という質問に true または false で答える道具です。
getClass() は、
このオブジェクトのクラス情報は何ですか
という情報を取り出す道具です。
鬼滅の刃風にたとえると、instanceof は「水の剣士ですか」と質問する確認札です。
getClass() は「この隊士の所属クラスが書かれた身分証」を取り出すようなものです。
図:instanceof で特定の型を判定する流れ
↓クリックすると拡大表示されます。

この図が示していること
この図では、Slayer[] 配列の中に WaterSlayer と MedicalSlayer のオブジェクトが入っている様子を表しています。
配列の型は Slayer[] なので、見た目はどちらも Slayer として扱われています。
しかし、実体は WaterSlayer と MedicalSlayer で異なります。
中央では、slayers[i] instanceof WaterSlayer という判定を行っています。
| 対象 | 実体 | 判定結果 |
|---|---|---|
| slayers[0] | WaterSlayer | true |
| slayers[1] | MedicalSlayer | false |
この図から分かることは、instanceof は変数の見た目の型ではなく、実際に指しているオブジェクトの型を見て判定するということです。
図:instanceof と getClass() の違い
↓クリックすると拡大表示されます。

この図が示していること
この図では、instanceof と getClass() の違いを比較しています。
instanceof は、特定のクラスかどうかを true または false で判定します。
そのため、if 文で処理を分けたいときに向いています。
一方、getClass() は、そのオブジェクトのクラス情報そのものを取り出します。
戻り値は Class クラスのオブジェクトです。
| しくみ | 返すもの | 使い方の感覚 |
|---|---|---|
| instanceof | true または false | この型ですか、と判定する |
| getClass() | Class オブジェクト | 実体のクラス情報を取り出す |
この図から分かることは、どちらも型に関係するしくみですが、目的が違うということです。
鬼滅の刃風に instanceof を整理する
instanceof は、鬼滅の刃風にたとえると、剣士オブジェクトに対して、
あなたは WaterSlayer クラスの剣士ですか
と問いかける演算子です。
WaterSlayer なら true。
MedicalSlayer なら false。
このように、まとめて扱っているオブジェクトの中から、特定の型を見分けられます。
| 状況 | instanceof の役割 |
|---|---|
| Slayer[] に複数の剣士が入っている | 実体の型を判定できる |
| WaterSlayer だけ処理したい | WaterSlayer かどうかを調べる |
| MedicalSlayer 以外を分けたい | if 文で条件分岐できる |
| 多態性で型が見えにくい | 実体を確認できる |
つまり instanceof は、
まとめて扱う便利さを保ちながら、必要なときにオブジェクトの型を見分けるための演算子
です。
この内容で押さえておきたいポイント
| ポイント | 内容 |
|---|---|
| instanceof | オブジェクトが特定のクラスのものか判定する演算子 |
| 戻り値 | true または false |
| 基本形 | object instanceof ClassName |
| 判定対象 | 変数の宣言型ではなく、実際に指しているオブジェクト |
| 抽象クラスとの関係 | 抽象クラス型でまとめた中から特定のサブクラスを判定できる |
| 多態性との関係 | まとめて扱う中で実体の型を見分けられる |
| getClass() との違い | instanceof は判定、getClass() はクラス情報の取得 |
| 便利な場面 | 特定クラスだけ処理を分けたいとき |
instanceof を理解すると、抽象クラスや多態性でまとめたオブジェクトを、必要な場面で安全に見分けられるようになります。
全員を Slayer として扱いながら、必要なときだけ WaterSlayer かどうかを判定する。
この感覚がつかめると、抽象クラス・多態性・型判定のつながりがかなり見えやすくなります。
