
Java道|getClass()の使い方と役割
見た目は同じ型で並んでいても、実体のクラスは一人ひとり違う。
getClass() を理解すると、オブジェクトが本当にどのクラスから作られたのかを正確につかめます。
Javaのオブジェクト指向では、スーパークラス型の変数でサブクラスのオブジェクトを扱えます。
たとえば、DemonSlayer 型の変数や配列に、DemonSlayer オブジェクトだけでなく、PillarSlayer オブジェクトを入れることもできます。
DemonSlayer slayer1 = new PillarSlayer();このように書くと、変数の型は DemonSlayer ですが、実際に入っているオブジェクトは PillarSlayer です。
ここで気になるのが、
今このオブジェクトは、実際にはどのクラスから作られたものなのか
という点です。
この「実体のクラス情報」を調べるために使うのが getClass() です。
getClass() は、Object クラスに用意されているメソッドです。
Javaのすべてのクラスは最終的に Object クラスを継承しているため、DemonSlayer や PillarSlayer のような自作クラスでも getClass() を使えます。
鬼滅の刃風にたとえると、getClass() は、隊士名簿では「鬼殺隊士」としてまとめられていても、実際には一般隊士なのか、柱なのか、水柱なのかを確認するための身分確認のようなものです。
getClass() は何をするメソッドなのか
getClass() は、そのオブジェクトが属しているクラスの情報を返すメソッドです。
つまり、オブジェクトの正体となるクラスを調べるために使います。
基本的な形は次のようになります。
object.getClass()このように呼び出すと、object が実際にどのクラスから作られたオブジェクトなのかを表す情報が返ってきます。
たとえば、次のような状態を考えます。
DemonSlayer slayer1 = new PillarSlayer();この場合、変数の型は DemonSlayer です。
しかし、実際に作られているオブジェクトは PillarSlayer です。
| 見るポイント | 内容 |
|---|---|
| 変数の型 | DemonSlayer |
| 実際のオブジェクト | PillarSlayer |
| getClass() で分かるもの | 実体のクラス情報 |
このとき slayer1.getClass() を呼び出すと、変数の型ではなく、実際のオブジェクトである PillarSlayer のクラス情報が分かります。
鬼滅の刃風にたとえると、名簿では鬼殺隊士として並んでいても、本人確認をすると「この隊士は柱です」と分かるようなイメージです。
なぜ getClass() が使えるのか
getClass() は Object クラスのメソッドです。
Javaのクラスは、すべて最終的に Object クラスにつながっています。
そのため、どんなクラスのオブジェクトでも getClass() を使えます。
これは、toString() や equals() と同じ考え方です。
| Object クラスの代表メソッド | 役割 |
|---|---|
| toString() | オブジェクトを文字列で表す |
| equals(Object obj) | オブジェクトが同じかどうか調べる |
| getClass() | オブジェクトのクラス情報を調べる |
鬼滅の刃風にたとえると、鬼殺隊士、柱、日輪刀、任務書など、いろいろな種類のオブジェクトがあっても、Java世界の共通機能として「自分がどのクラスなのかを示す機能」を持っているということです。
↓クリックすると拡大表示されます。

getClass() が返すのは何か
getClass() が返すのは、単なる文字列ではありません。
getClass() は、Class クラスのオブジェクト を返します。
Class cl = object.getClass();この Class オブジェクトには、そのオブジェクトのクラス情報が入っています。
| メソッド | 戻り値 |
|---|---|
| getClass() | Class クラスのオブジェクト |
ここは少し難しく感じるかもしれませんが、最初は次のように考えると分かりやすいです。
| 考え方 | 内容 |
|---|---|
| オブジェクト | 実際に作られたもの |
| getClass() | そのオブジェクトの正体を調べる |
| Class オブジェクト | クラス情報が入った情報カード |
鬼滅の刃風にたとえると、隊士本人を見て「この人は PillarSlayer クラスです」と書かれた身分証カードを取り出すようなイメージです。
オブジェクトのクラス情報を調べる
ファイル名:Sample9.java
class DemonSlayer
{
protected String name;
protected String rank;
public DemonSlayer()
{
name = "隊士未登録";
rank = "階級未設定";
System.out.println("鬼殺隊士を作成しました。");
}
}
class PillarSlayer extends DemonSlayer
{
private int area;
public PillarSlayer()
{
area = 0;
System.out.println("柱クラスの隊士を作成しました。");
}
}
class Sample9
{
public static void main(String[] args)
{
DemonSlayer[] slayers;
slayers = new DemonSlayer[2];
slayers[0] = new DemonSlayer();
slayers[1] = new PillarSlayer();
for(int i = 0; i < slayers.length; i++){
Class cl = slayers[i].getClass();
System.out.println((i + 1) + "番目のオブジェクトのクラスは"
+ cl + "です。");
}
}
}実行結果
鬼殺隊士を作成しました。
鬼殺隊士を作成しました。
柱クラスの隊士を作成しました。
1番目のオブジェクトのクラスはclass DemonSlayerです。
2番目のオブジェクトのクラスはclass PillarSlayerです。Sample9.java の中心になる部分
このプログラムで大切なのは、配列の型が DemonSlayer[] になっているところです。
DemonSlayer[] slayers;
slayers = new DemonSlayer[2];この配列は DemonSlayer 型の配列です。
そのため、DemonSlayer のオブジェクトを入れられます。
slayers[0] = new DemonSlayer();さらに、PillarSlayer は DemonSlayer を継承しているため、PillarSlayer オブジェクトも入れられます。
slayers[1] = new PillarSlayer();整理すると、次のようになります。
| 配列の位置 | 変数としての型 | 実際に入っているオブジェクト |
|---|---|---|
| slayers[0] | DemonSlayer | DemonSlayer |
| slayers[1] | DemonSlayer | PillarSlayer |
見た目はどちらも DemonSlayer 型の配列要素です。
しかし、実体は異なります。
ここで getClass() を使うと、それぞれのオブジェクトの正体を確認できます。
なぜ配列の型ではなく実体のクラスが分かるのか
getClass() は、変数の宣言型を返しているのではありません。
getClass() が見るのは、実際にその変数や配列要素が指しているオブジェクトのクラスです。
そのため、次のような結果になります。
| 調べる対象 | 配列としての型 | 実体 | getClass() の結果 |
|---|---|---|---|
| slayers[0] | DemonSlayer | DemonSlayer | class DemonSlayer |
| slayers[1] | DemonSlayer | PillarSlayer | class PillarSlayer |
ここが getClass() の重要なところです。
DemonSlayer[] 配列に入っているからといって、すべてが DemonSlayer の実体だとは限りません。
サブクラスの PillarSlayer オブジェクトが入っている場合もあります。
鬼滅の刃風にたとえると、隊士名簿では全員を鬼殺隊士として並べていても、一人ずつ確認すると「一般隊士」と「柱」が混ざっていることが分かる、ということです。
Class クラスのオブジェクトとは何か
Sample9.java では、getClass() の戻り値を Class 型の変数 cl に入れています。
Class cl = slayers[i].getClass();この cl には、オブジェクトのクラス情報が入っています。
学習段階では、Class クラスのオブジェクトを、次のようにイメージすると分かりやすいです。
| もの | 鬼滅の刃風のイメージ |
|---|---|
| DemonSlayer オブジェクト | 実際の隊士本人 |
| getClass() | 隊士の身分証を確認する動作 |
| Class オブジェクト | どのクラスの隊士かを示す身分証カード |
つまり Class オブジェクトは、クラスそのものについての情報を持っている特別な情報箱です。
たとえば、getClass() の結果を出力すると、次のような表示になります。
class DemonSlayer
class PillarSlayerこれは、そのオブジェクトがどのクラスに属しているかを示しています。
出力結果から分かること
Sample9.java の出力では、次のように表示されています。
1番目のオブジェクトのクラスはclass DemonSlayerです。
2番目のオブジェクトのクラスはclass PillarSlayerです。ここから分かるのは、getClass() がきちんとオブジェクトの実体を見ているということです。
| 順番 | 配列要素 | 実体 | getClass() の結果 |
|---|---|---|---|
| 1番目 | slayers[0] | DemonSlayer | class DemonSlayer |
| 2番目 | slayers[1] | PillarSlayer | class PillarSlayer |
このように、スーパークラス型でまとめて扱っていても、getClass() を使えば、実際のオブジェクトのクラスを確認できます。
getClass() はどんな場面で便利なのか
getClass() は、オブジェクトの種類を確認したいときに便利です。
たとえば、次のような場面があります。
| 場面 | getClass() が役立つ理由 |
|---|---|
| 配列に複数種類のオブジェクトが入っている | どのクラスの実体か確認できる |
| コレクションに派生クラスが混ざっている | 中身の正体を調べられる |
| デバッグ中に型を確認したい | 変数の型と実体の違いを確認できる |
| ポリモーフィズムの動きを学びたい | 実際にどのクラスのオブジェクトか分かる |
鬼滅の刃風にたとえると、隊士名簿を見ながら、
この札の先にいるのは、一般隊士なのか、柱なのか
を確認するようなものです。
getClass() とポリモーフィズムのつながり
getClass() は、ポリモーフィズムの理解とも深くつながります。
ポリモーフィズムでは、スーパークラス型の変数でサブクラスのオブジェクトを扱えます。
たとえば、次のような状態です。
DemonSlayer slayer1 = new PillarSlayer();この場合、
| 見るポイント | 内容 |
|---|---|
| 変数の型 | DemonSlayer |
| 実体 | PillarSlayer |
になります。
この状態で show() のようなオーバーライドされたメソッドを呼び出すと、実体である PillarSlayer 側のメソッドが動きます。
そして getClass() を使えば、その「実体が何か」を確認できます。
| メソッド | 見えるもの |
|---|---|
| オーバーライドされたメソッド呼び出し | 実体に応じた処理が動く |
| getClass() | 実体のクラス情報が分かる |
つまり getClass() は、
ポリモーフィズムで見えにくくなりがちなオブジェクトの正体を確認するためのメソッド
と考えると分かりやすいです。
Object クラスとのつながりを意識する
getClass() は、toString() や equals() と同じく Object クラスのメソッドです。
そのため、Javaのすべてのクラスで使えます。
| Object 由来のメソッド | 役割 |
|---|---|
| toString() | オブジェクトを文字列で表す |
| equals() | オブジェクトが同じかどうかを調べる |
| getClass() | オブジェクトのクラス情報を調べる |
Object クラスを理解していると、なぜこれらのメソッドがどのクラスでも使えるのかが自然につながります。
鬼滅の刃風にたとえると、どの隊士や道具も、Java世界の共通の土台である Object から基本機能を受け継いでいるということです。
図:getClass() が実体のクラスを調べる流れ
↓クリックすると拡大表示されます。

この図が示していること
この図では、DemonSlayer[] 配列の中に、DemonSlayer オブジェクトと PillarSlayer オブジェクトが入っている様子を表しています。
配列の型は DemonSlayer[] です。
しかし、slayers[0] の実体は DemonSlayer、slayers[1] の実体は PillarSlayer です。
getClass() を呼び出すと、配列の型ではなく、実際に入っているオブジェクトのクラス情報が返されます。
| 呼び出し | 結果 |
|---|---|
| slayers[0].getClass() | class DemonSlayer |
| slayers[1].getClass() | class PillarSlayer |
この図から分かることは、getClass() は「見た目の型」ではなく「実体のクラス」を調べるメソッドだということです。
図:Object クラスから受け継ぐ getClass()
↓クリックすると拡大表示されます。

この図が示していること
この図では、getClass() が Object クラスにある基本メソッドであり、DemonSlayer や PillarSlayer に受け継がれていることを表しています。
Object クラスには、toString()、equals()、getClass() のような基本メソッドがあります。
DemonSlayer は Object を継承し、PillarSlayer は DemonSlayer を継承しています。
そのため、PillarSlayer も最終的には Object 由来の getClass() を使えます。
この図から分かることは、getClass() が特定のクラスだけの機能ではなく、Javaのすべてのオブジェクトが使える共通機能だということです。
鬼滅の刃風に getClass() を整理する
getClass() は、鬼滅の刃風にたとえると、隊士オブジェクトに対して、
あなたはどの隊士型に属していますか
と確認するメソッドです。
見た目は同じ DemonSlayer[] 配列に入っていても、実際には次のように違うクラスのオブジェクトが入っている場合があります。
| 配列上の見た目 | 実体 |
|---|---|
| DemonSlayer 型として扱う | DemonSlayer オブジェクト |
| DemonSlayer 型として扱う | PillarSlayer オブジェクト |
このとき getClass() を使えば、それぞれの実体を確認できます。
| 実体 | getClass() の結果 |
|---|---|
| DemonSlayer | class DemonSlayer |
| PillarSlayer | class PillarSlayer |
つまり getClass() は、
オブジェクトの正体となるクラスを確認するためのメソッド
です。
この内容で押さえておきたいポイント
| ポイント | 内容 |
|---|---|
| getClass() | オブジェクトが属しているクラス情報を返すメソッド |
| 定義元 | Object クラス |
| すべてのクラスで使える理由 | Javaのすべてのクラスは Object を継承しているから |
| 戻り値 | Class クラスのオブジェクト |
| 変数の型との違い | getClass() は変数の宣言型ではなく、実体のクラスを見る |
| 配列での使い方 | スーパークラス型配列に入った各オブジェクトの正体を確認できる |
| ポリモーフィズムとの関係 | スーパークラス型でまとめた中身の実体を確認できる |
| 便利な場面 | デバッグ、学習、配列やコレクション内の型確認 |
getClass() を理解すると、スーパークラス型でまとめて扱っているオブジェクトの中身が、実際にはどのクラスなのかを確認できるようになります。
見た目の型と実体のクラスを分けて考える。
この感覚がつかめると、ポリモーフィズムや Object クラスの理解もさらに深まります。
