
Java超|instanceofの使い方と型判定のしくみ
見た目は同じ戦士名簿の中でも、実体の型までは同じとは限りません。instanceof を理解すると、オブジェクトの正体を見分けながら、安全に処理を分けられるようになります。
抽象クラスを使うと、共通の親クラスの型で、いろいろなサブクラスのオブジェクトをまとめて扱えるようになります。
たとえば、ドラゴンボール風に考えると、Warrior という共通の戦士型を用意して、その配列の中に SuperSaiyanWarrior や SupportWarrior のような具体的な戦士オブジェクトを入れられます。
これはとても便利です。
共通の型でまとめられるので、同じ配列で管理できます。
さらに、共通メソッドも同じ形で呼び出せます。
たとえば、Warrior[] warriors という配列に、スーパーサイヤ人戦士と支援戦士を一緒に入れられます。
Warrior[] warriors = new Warrior[2];
warriors[0] = new SuperSaiyanWarrior("悟空", "亀仙流", 1);
warriors[1] = new SupportWarrior("悟飯", "神流", "気の感知と仲間支援");配列の型は Warrior[] です。
しかし、実際に入っているオブジェクトは、SuperSaiyanWarrior と SupportWarrior です。
ここで大切になるのは、見た目の型と実体の型が違う場合があるという点です。
| 確認したいこと | 例 |
|---|---|
| この戦士はスーパーサイヤ人戦士なのか | SuperSaiyanWarrior かどうか |
| この戦士は支援戦士なのか | SupportWarrior かどうか |
| 特定のクラスだけに処理したい | SuperSaiyanWarrior だけに変身訓練を行う |
このようなときに使うのが instanceof 演算子です。
instanceof を使うと、変数が指しているオブジェクトが、特定のクラスのものかどうかを true または false で判定できます。
つまり instanceof は、オブジェクトの型を判定するための道具です。
ドラゴンボール風にたとえると、instanceof は、戦士名簿に並んでいる戦士に対して、
あなたは SuperSaiyanWarrior クラスの戦士ですか
と確認するようなものです。
名簿上は全員 Warrior として並んでいても、実体はそれぞれ違います。
instanceof を使えば、その中から特定の戦士型だけを見分けられます。
instanceof は何をする演算子なのか
instanceof は、左側の変数が指しているオブジェクトが、右側のクラスのものかどうかを調べる演算子です。
基本の形は次のようになります。
object instanceof ClassNameたとえば、次のように書けます。
warriors[i] instanceof SuperSaiyanWarriorこれは、warriors[i] が指しているオブジェクトが SuperSaiyanWarrior クラスのものなら true、そうでなければ false になります。
| 式 | 意味 |
|---|---|
| warriors[i] instanceof SuperSaiyanWarrior | warriors[i] の実体が SuperSaiyanWarrior かどうか調べる |
| warriors[i] instanceof SupportWarrior | warriors[i] の実体が SupportWarrior かどうか調べる |
ここで大切なのは、instanceof は変数の宣言型だけを見るのではなく、実際に指しているオブジェクトの型を見て判定するという点です。
たとえば、warriors という配列の型が Warrior[] だったとしても、中に入っている実体は SuperSaiyanWarrior かもしれません。
その場合、次の判定は true になります。
warriors[i] instanceof SuperSaiyanWarriorドラゴンボール風にたとえると、戦士名簿上は Warrior として並んでいても、本人確認をすれば、スーパーサイヤ人戦士なのか、支援戦士なのかを判定できるということです。
なぜ instanceof が必要になるのか
抽象クラスやスーパークラスを使うと、複数の種類のオブジェクトをまとめて扱えます。
たとえば、次のような配列を考えます。
Warrior[] warriors;この配列には、Warrior を継承したサブクラスのオブジェクトを入れられます。
| 配列に入れる実体 | 説明 |
|---|---|
| SuperSaiyanWarrior | スーパーサイヤ人戦士 |
| SupportWarrior | 支援戦士 |
配列の型だけを見ると、どちらも Warrior として扱われます。
しかし、実際の中身は SuperSaiyanWarrior だったり、SupportWarrior だったりします。
このとき、特定のサブクラスだけを見分けたいことがあります。
たとえば、SuperSaiyanWarrior だけに変身段階の確認を行いたい場合です。
また、SupportWarrior だけに支援能力の確認をさせたい場合もあります。
こうしたときに instanceof を使うと、まとめて扱っているオブジェクトの中から、特定の型だけを判定できます。
つまり instanceof は、多態性でまとめたオブジェクトを、必要に応じて見分けるための演算子です。
ドラゴンボール風に言うと、戦士管理本部では全員を Warrior としてまとめて管理します。
しかし、訓練内容を分けたいときには、
スーパーサイヤ人戦士か。
支援戦士か。
を見分ける必要があります。
その判定に使うのが instanceof です。
図:instanceof で特定の型を判定する流れ

この図が示していること
この図では、Warrior[] 配列の中に SuperSaiyanWarrior と SupportWarrior のオブジェクトが入っている様子を表しています。
配列の型は Warrior[] なので、見た目はどちらも Warrior として扱われています。
しかし、実体は SuperSaiyanWarrior と SupportWarrior で異なります。
中央では、次の判定を行っています。
warriors[i] instanceof SuperSaiyanWarrior| 対象 | 実体 | 判定結果 |
|---|---|---|
| warriors[0] | SuperSaiyanWarrior | true |
| warriors[1] | SupportWarrior | false |
この図から分かることは、instanceof は変数の見た目の型ではなく、実際に指しているオブジェクトの型を見て判定するということです。
ドラゴンボール風に考える instanceof の感覚
ドラゴンボール風にたとえると、instanceof は、戦士オブジェクトに対して、
あなたは本当にこの型の戦士ですか
と確認する判定札のようなものです。
たとえば、Warrior[] 配列に次のような戦士が入っているとします。
| 配列要素 | 実体 |
|---|---|
| warriors[0] | SuperSaiyanWarrior |
| warriors[1] | SupportWarrior |
このとき、次の判定を行います。
warriors[i] instanceof SuperSaiyanWarriorすると、SuperSaiyanWarrior の実体なら true です。
SupportWarrior の実体なら false です。
| 実体 | warriors[i] instanceof SuperSaiyanWarrior |
|---|---|
| SuperSaiyanWarrior | true |
| SupportWarrior | false |
これは、全員を Warrior としてまとめて扱いながら、必要なときだけ特定の戦士型を見分けるためのしくみです。
たとえば、スーパーサイヤ人戦士だけに変身訓練を行いたい場合、instanceof で SuperSaiyanWarrior かどうかを判定できます。
支援戦士には支援訓練、スーパーサイヤ人戦士には変身訓練、というように処理を分けられるわけです。
instanceof の動きを確認する
ファイル名:Sample2.java
abstract class Warrior
{
protected int speed;
public void setSpeed(int s)
{
speed = s;
System.out.println("速度を" + speed + "にしました。");
}
abstract void show();
}
class SuperSaiyanWarrior extends Warrior
{
private String name;
private String styleName;
private int transformationLevel;
public SuperSaiyanWarrior(String n, String s, int level)
{
name = n;
styleName = s;
transformationLevel = level;
System.out.println(name + " 変身段階" + transformationLevel + "のスーパーサイヤ人戦士を作成しました。");
}
public void show()
{
System.out.println("スーパーサイヤ人戦士の名前は" + name + "です。");
System.out.println("流派は" + styleName + "です。");
System.out.println("変身段階は" + transformationLevel + "です。");
System.out.println("速度は" + speed + "です。");
}
}
class SupportWarrior extends Warrior
{
private String name;
private String styleName;
private String supportSkill;
public SupportWarrior(String n, String s, String skill)
{
name = n;
styleName = s;
supportSkill = skill;
System.out.println(name + " 支援能力「" + supportSkill + "」の支援戦士を作成しました。");
}
public void show()
{
System.out.println("支援戦士の名前は" + name + "です。");
System.out.println("流派は" + styleName + "です。");
System.out.println("支援能力は" + supportSkill + "です。");
System.out.println("速度は" + speed + "です。");
}
}
class Sample2
{
public static void main(String[] args)
{
Warrior[] warriors;
warriors = new Warrior[2];
warriors[0] = new SuperSaiyanWarrior("悟空", "亀仙流", 1);
warriors[1] = new SupportWarrior("悟飯", "神流", "気の感知と仲間支援");
for(int i = 0; i < warriors.length; i++){
if(warriors[i] instanceof SuperSaiyanWarrior)
System.out.println((i + 1)
+ "番目のオブジェクトはSuperSaiyanWarriorクラスです。");
else
System.out.println((i + 1)
+ "番目のオブジェクトはSuperSaiyanWarriorクラスではありません。");
}
}
}実行結果
悟空 変身段階1のスーパーサイヤ人戦士を作成しました。
悟飯 支援能力「気の感知と仲間支援」の支援戦士を作成しました。
1番目のオブジェクトはSuperSaiyanWarriorクラスです。
2番目のオブジェクトはSuperSaiyanWarriorクラスではありません。Sample2.java の中心になる部分
このプログラムでは、まず抽象クラス Warrior を用意しています。
abstract class WarriorWarrior は抽象クラスなので、直接 new Warrior() のようにオブジェクトを作ることはできません。
しかし、Warrior 型の配列を作ることはできます。
Warrior[] warriors;
warriors = new Warrior[2];そして、その配列には Warrior を継承した具体的なサブクラスのオブジェクトを入れられます。
warriors[0] = new SuperSaiyanWarrior("悟空", "亀仙流", 1);
warriors[1] = new SupportWarrior("悟飯", "神流", "気の感知と仲間支援");配列の中身を整理すると、次のようになります。
| 配列の位置 | 変数としての型 | 実際に入っているオブジェクト |
|---|---|---|
| warriors[0] | Warrior | SuperSaiyanWarrior |
| warriors[1] | Warrior | SupportWarrior |
見た目の型はどちらも Warrior です。
しかし、実体は SuperSaiyanWarrior と SupportWarrior で異なります。
そこで、ループの中で instanceof を使って、SuperSaiyanWarrior かどうかを判定しています。
warriors[i] instanceof SuperSaiyanWarriorこの式が true なら SuperSaiyanWarrior、false なら SuperSaiyanWarrior ではない、という判断ができます。
true と false はどう決まるのか
このプログラムでは、warriors[0] には SuperSaiyanWarrior オブジェクトが入っています。
そのため、次の判定は true になります。
warriors[0] instanceof SuperSaiyanWarrior一方、warriors[1] には SupportWarrior オブジェクトが入っています。
そのため、次の判定は false になります。
warriors[1] instanceof SuperSaiyanWarrior表で整理すると、次のようになります。
| 判定する式 | 結果 | 理由 |
|---|---|---|
| warriors[0] instanceof SuperSaiyanWarrior | true | 実体が SuperSaiyanWarrior だから |
| warriors[1] instanceof SuperSaiyanWarrior | false | 実体が SupportWarrior だから |
ここで大切なのは、warriors[0] も warriors[1] も、配列上は Warrior 型として扱われていることです。
しかし instanceof は、変数の宣言型ではなく、実体のクラスを見て判定します。
ドラゴンボール風にたとえると、戦士名簿には全員 Warrior として並んでいても、実際にスカウターで確認すると、スーパーサイヤ人戦士なのか支援戦士なのかを見分けられるということです。
なぜ変数の型ではなく実体で判定するのか
ここは多態性と深くつながるポイントです。
多態性では、スーパークラス型や抽象クラス型の変数で、サブクラスのオブジェクトを扱えます。
たとえば、今回の配列では次のようになっています。
| 配列要素 | 見た目の型 | 実体 |
|---|---|---|
| warriors[0] | Warrior | SuperSaiyanWarrior |
| warriors[1] | Warrior | SupportWarrior |
このように、見た目の型と実体のクラスが違うことがあります。
instanceof は、この実体を見て判定します。
だから、Warrior 型の配列でまとめていても、その中から SuperSaiyanWarrior だけを見つけることができます。
これは、多態性でまとめて扱う便利さを保ちながら、必要なときだけ個別の型を確認できるということです。
instanceof が便利な場面
instanceof は、特定のクラスのオブジェクトにだけ処理をしたいときに便利です。
たとえば、ドラゴンボール風に考えると、次のような場面です。
| 場面 | instanceof の使い方 |
|---|---|
| スーパーサイヤ人戦士だけに変身訓練を行う | SuperSaiyanWarrior かどうか判定する |
| 支援戦士だけに支援準備をさせる | SupportWarrior かどうか判定する |
| 特定クラスだけ別メッセージを出す | if 文で処理を分ける |
| 配列の中身の型を確認する | ループ中に instanceof で調べる |
つまり instanceof は、まとめて扱う便利さを保ちながら、必要なときだけ型によって処理を分けるための道具です。
たとえば、Warrior[] 配列で全員を管理しているとします。
通常は show() を呼び出せば、実体ごとの show() が動きます。
しかし、SuperSaiyanWarrior だけに専用メッセージを出したい場合は、instanceof で判定してから処理を分けられます。
if(warriors[i] instanceof SuperSaiyanWarrior)
System.out.println("変身訓練の対象です。");このように、型によって条件分岐したい場面で instanceof は役立ちます。
抽象クラスと instanceof は相性がよい
抽象クラスを使うと、サブクラスのオブジェクトを共通の型でまとめられます。
今回なら、SuperSaiyanWarrior と SupportWarrior を Warrior[] 配列でまとめています。
| 抽象クラスを使う利点 | 内容 |
|---|---|
| 共通メソッドを同じ形で呼べる | show() や setSpeed() など |
| 複数のサブクラスを1つの配列で管理できる | Warrior[] にまとめられる |
| 多態性を使える | 実体ごとにメソッドの動きが変わる |
一方で、まとめて扱っている中から「このクラスだけを見分けたい」という場面もあります。
そこで instanceof が役立ちます。
ドラゴンボール風にたとえると、まずは全員を Warrior として整列させます。
そのうえで、必要な場面だけ「スーパーサイヤ人戦士は誰か」を見分けるような使い方です。
共通処理は Warrior 型でまとめる。
個別処理が必要なときは instanceof で見分ける。
この組み合わせができると、抽象クラスと多態性をかなり実践的に使えるようになります。
図:抽象クラス型の配列と instanceof の関係

この図が示していること
この図では、抽象クラス Warrior 型の配列で複数のサブクラスをまとめ、必要なときに instanceof で特定の型を見分ける流れを表しています。
Warrior[] には、SuperSaiyanWarrior と SupportWarrior の両方を入れられます。
配列上はどちらも Warrior として扱われます。
しかし、instanceof を使うと、実体が SuperSaiyanWarrior かどうかを判定できます。
| 対象 | 実体 | instanceof SuperSaiyanWarrior |
|---|---|---|
| warriors[0] | SuperSaiyanWarrior | true |
| warriors[1] | SupportWarrior | false |
この図から分かることは、抽象クラス型でまとめる便利さと、必要なときだけ型を見分ける柔軟さを両立できるということです。
instanceof と getClass() の違い
instanceof は、前に学んだ getClass() と少し似ています。
どちらもオブジェクトの型に関係するからです。
ただし、役割は違います。
| しくみ | 役割 | 向いている場面 |
|---|---|---|
| instanceof | 特定のクラスかどうかを true または false で判定する | if 文で処理を分けたいとき |
| getClass() | そのオブジェクトのクラス情報そのものを取り出す | 実体のクラス情報を確認したいとき |
instanceof は、このオブジェクトは SuperSaiyanWarrior ですか、という質問に true または false で答える道具です。
getClass() は、このオブジェクトのクラス情報は何ですか、という情報を取り出す道具です。
ドラゴンボール風にたとえると、instanceof は「スーパーサイヤ人戦士ですか」と質問する確認札です。
getClass() は「この戦士の所属クラスが書かれた身分証」を取り出すようなものです。
instanceof は if 文で処理を分けたいときに使いやすい
instanceof は true または false を返すため、if 文と相性がよいです。
たとえば、次のように書けます。
if(warriors[i] instanceof SuperSaiyanWarrior)
System.out.println("スーパーサイヤ人専用の訓練を行います。");
else
System.out.println("通常訓練または支援訓練を行います。");このようにすると、SuperSaiyanWarrior の実体だけに専用処理を行えます。
| 判定結果 | 処理 |
|---|---|
| true | スーパーサイヤ人専用処理を行う |
| false | それ以外の処理を行う |
一方、getClass() はクラス情報そのものを取り出すため、デバッグや確認に向いています。
System.out.println(warriors[i].getClass());このようにすると、class SuperSaiyanWarrior や class SupportWarrior のように、実体のクラス情報を表示できます。
つまり、処理を分けたいなら instanceof。
正体の情報を確認したいなら getClass()。
このように整理すると分かりやすいです。
図:instanceof と getClass() の違い

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