Menu
Coddy logo textTech

instanceof 演算子

CoddyのJavaジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 31/87。

前のレッスンでは、オブジェクトが実際にはキャスト先の型でない場合、ダウンキャストが ClassCastException で失敗する可能性があることを示しました。instanceof 演算子を使うと、キャストする前にオブジェクトの型を確認できるため、この問題を解決できます。

構文は straightforward です。object instanceof ClassName は、object がその class(またはそのサブクラス)のインスタンスである場合に true を返します。

Animal animal = new Dog();

if (animal instanceof Dog) {
    Dog dog = (Dog) animal;
    dog.bark();  // Dog固有のメソッドを呼び出しても安全
}

このチェックは、cast が成功することを確認して、実行時エラーを防ぎます。この演算子は、階層内の親型に対しても true を返します。

Dog dog = new Dog();
System.out.println(dog instanceof Dog);     // true
System.out.println(dog instanceof Animal);  // true
System.out.println(dog instanceof Object);  // true

Java 16以降では、パターンマッチングを使用して、check と cast を1つのステップに組み合わせることができます。

if (animal instanceof Dog dog) {
    dog.bark();  // 'dog' は既にキャスト済みで使用可能です
}

このより簡潔な構文では、個別のキャスト行が不要になります。instanceofnull に対してテストすると false を返すため、個別に null チェックを行う必要はありません。

challenge icon

チャレンジ

簡単

instanceof演算子を使用して、さまざまな車両タイプを安全に識別・処理する車両検査システムを構築しましょう。車両の階層を作成し、専用の機能にアクセスする前に各車両の実際のタイプを確認するコードを記述します。

コードを4つのファイルに分けて整理します。

  • Vehicle.java:すべての車両で共有する Base classを作成します。すべての車両にはmodel field(String)があります。これを初期化するconstructor、getter method getModel()、そしてinspect()を出力するmethod Inspecting vehicle: [model]を含めます。
  • Car.java:Vehicleをextendsするclassを作成します。Carには追加のnumDoors field(int)があります。親のinitializationにはsuperを使用します。[model] has [numDoors] doorsを出力するmethod checkDoors()を追加します。
  • Motorcycle.java:Vehicleをextendsする別のclassを作成します。MotorcycleにはhasSidecar field(boolean)があります。booleanの値に応じて、[model] has a sidecarまたは[model] has no sidecarのいずれかを出力するmethod checkSidecar()を追加します。
  • Main.java:ここでinstanceofが重要になります!4つのinputsを受け取ります。carのmodel、doorsの数、motorcycleのmodel、そしてsidecarがあるかどうか(true/false)です。

    CarとMotorcycleを含むVehicle referencesのarrayを作成します。その後、arrayをLoopし、各vehicleについて次の処理を行います。

    • Baseのinspect() methodをCallする
    • instanceofを使用してCarかどうかをcheckする。Carの場合は、安全にdowncastしてcheckDoors()をCallする
    • instanceofを使用してMotorcycleかどうかをcheckする。Motorcycleの場合は、安全にdowncastしてcheckSidecar()をCallする

4つのinputsを受け取ります。carのmodel(String)、doorsの数(int)、motorcycleのmodel(String)、そしてhas sidecar(boolean)です。

出力には4行が表示されます。各vehicleについて、inspection messageに続いて、そのtype-specific checkが表示されます。instanceof operatorにより、実際のCarに対してのみCarのmethodsを、実際のMotorcycleに対してのみMotorcycleのmethodsをCallできるため、ClassCastExceptionを防止できます!

自分で試してみよう

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // 入力を読み取る
        String carModel = scanner.nextLine();
        int numDoors = Integer.parseInt(scanner.nextLine());
        String motorcycleModel = scanner.nextLine();
        boolean hasSidecar = Boolean.parseBoolean(scanner.nextLine());
        
        // TODO: carModel と numDoors で Car オブジェクトを作成する
        
        // TODO: motorcycleModel と hasSidecar で Motorcycle オブジェクトを作成する
        
        // TODO: Car と Motorcycle を含む Vehicle 参照の配列を作成する
        
        // TODO: 配列をループして各 vehicle について:
        // 1. inspect() メソッドを呼び出す
        // 2. instanceof を使って Car かどうかを確認し、ダウンキャストして checkDoors() を呼び出す
        // 3. instanceof を使って Motorcycle かどうかを確認し、ダウンキャストして checkSidecar() を呼び出す
    }
}
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

オブジェクト指向プログラミングのすべてのレッスン

自分で練習してみよう: Javaオンラインコンパイラ