0Pricing
Java Academy · レッスン

instanceof 演算子

キャスト前に instanceof でオブジェクトの型を確認し、ClassCastException を回避します。

「instanceof 演算子」はCoddyKit上の無料Java Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはJava Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Java Academyコースには全4レッスンが含まれています。

instanceof演算子

instanceof演算子は、実行時にオブジェクトが指定した型のインスタンスかどうかを確認します。trueまたはfalseを返し、キャスト前にClassCastExceptionが発生するのを防ぎます。

instanceofの基本的な使い方

安全にキャストする前に、instanceofを使ってオブジェクトの実行時の型を確認します。

Object obj = "Hello, Java!";

if (obj instanceof String) {
    String s = (String) obj;
    System.out.println(s.toUpperCase()); // HELLO, JAVA!
}

Object num = Integer.valueOf(42);
System.out.println(num instanceof Integer); // true
System.out.println(num instanceof String);  // false

継承とinstanceof

instanceofは、オブジェクトがそのクラスまたは任意のサブクラス(あるいは実装している任意のインターフェース)のインスタンスである場合にtrueを返します。

class Animal {}
class Dog extends Animal {}
class Cat extends Animal {}

Animal a = new Dog();

System.out.println(a instanceof Animal); // true
System.out.println(a instanceof Dog);    // true
System.out.println(a instanceof Cat);    // false

パターンマッチングinstanceof(Java 16以降)

Java 16ではinstanceofにパターンマッチングが導入されました。同じ式の中でバインディング変数を宣言できるため、明示的なキャストが不要になります。

Object shape = "circle";

// Old way
if (shape instanceof String) {
    String s = (String) shape;
    System.out.println(s.length());
}

// New way (Java 16+) — binding variable 's' is in scope
if (shape instanceof String s) {
    System.out.println(s.length()); // 6
}

メソッド内のパターンマッチング

パターンマッチングを使うと、型に基づく振り分けを簡潔かつ安全に記述できます。バインディング変数のスコープは、条件がtrueであることが分かっている範囲に限られます。

sealed interface Shape permits Circle, Rectangle {}
record Circle(double radius) implements Shape {}
record Rectangle(double width, double height) implements Shape {}

static double area(Shape s) {
    if (s instanceof Circle c) {
        return Math.PI * c.radius() * c.radius();
    } else if (s instanceof Rectangle r) {
        return r.width() * r.height();
    }
    throw new IllegalArgumentException("Unknown shape");
}

System.out.println(area(new Circle(5)));         // 78.53...
System.out.println(area(new Rectangle(4, 6)));   // 24.0

nullとinstanceof

null instanceof AnyTypeは常にfalseを返し、例外をスローすることはありません。そのため、instanceofはキャスト前の確認をnull安全に行う方法になります。

String s = null;
System.out.println(s instanceof String); // false (not NPE)

Object o = null;
if (o instanceof Number n) {
    System.out.println(n.intValue());
} else {
    System.out.println("Not a number (or null)"); // prints this
}

switch式とパターンマッチング

Java 21ではパターンマッチングがswitch式に拡張され、if-elseの連鎖を使わずに、型に基づく振り分けを簡潔に記述できます。

static String describe(Object obj) {
    return switch (obj) {
        case Integer i -> "Integer: " + i;
        case Double d  -> "Double: " + d;
        case String s  -> "String of length " + s.length();
        case null      -> "null value";
        default        -> "Unknown: " + obj.getClass().getSimpleName();
    };
}

System.out.println(describe(42));       // Integer: 42
System.out.println(describe(3.14));     // Double: 3.14
System.out.println(describe("hello")); // String of length 5
System.out.println(describe(null));     // null value

instanceofを使わないClassCastException

事前に確認せずにキャストすると、実行時にClassCastExceptionが発生します。これはレガシーコードでよくあるバグで、パターンマッチングによって防ぎやすくなります。

Object obj = "I am a String";

try {
    Integer i = (Integer) obj; // ClassCastException!
} catch (ClassCastException e) {
    System.out.println("Cannot cast String to Integer");
}

// Safe version
if (obj instanceof Integer i) {
    System.out.println("Is integer: " + i);
} else {
    System.out.println("Not an integer");
}

実践:混在リストの処理

実際の開発での使用例です。パターンマッチングを使って、さまざまな型のオブジェクトが混在するリストを処理します。

import java.util.List;

List<Object> events = List.of(
    "User login", 42, 3.14, "Payment processed", 100
);

double numericSum = 0;
for (Object e : events) {
    if (e instanceof Integer n) numericSum += n;
    else if (e instanceof Double d) numericSum += d;
    else if (e instanceof String s) System.out.println("Log: " + s);
}
System.out.printf("Numeric sum: %.2f%n", numericSum); // 145.14

シールドクラスと網羅的なマッチング

シールドクラス(Java 17以降)は、継承できるクラスを制限します。パターンマッチングswitchと組み合わせると、コンパイラーがすべてのケースを網羅しているか検証できるため、defaultケースは必要ありません。

sealed interface Notification permits EmailNotification, SmsNotification {}
record EmailNotification(String to, String body) implements Notification {}
record SmsNotification(String phone, String text) implements Notification {}

static void send(Notification n) {
    switch (n) {
        case EmailNotification e ->
            System.out.println("Email to " + e.to() + ": " + e.body());
        case SmsNotification s ->
            System.out.println("SMS to " + s.phone() + ": " + s.text());
        // no default needed — compiler knows all cases are covered
    }
}

ガード付きパターン

パターンマッチングでは、when(Java 21)のガードを使って、型チェックと同時にboolean条件を追加できます。

static String classify(Number n) {
    return switch (n) {
        case Integer i when i < 0  -> "negative int: " + i;
        case Integer i when i == 0 -> "zero";
        case Integer i             -> "positive int: " + i;
        case Double d              -> "double: " + d;
        default                    -> "other number";
    };
}

System.out.println(classify(-5));  // negative int: -5
System.out.println(classify(0));   // zero
System.out.println(classify(7));   // positive int: 7

クイックチェック

次の式は何を返すでしょうか?

Object obj = null;
boolean result = obj instanceof String;
System.out.println(result);

復習:instanceof演算子

重要なポイント:

  • instanceofは実行時の型を確認し、ClassCastExceptionを防ぎます
  • nullに対してはfalseを返し、NPEをスローすることはありません
  • クラス自身と、そのすべてのサブクラスおよび実装インターフェースに対してtrueを返します
  • Java 16以降のパターンマッチング:if (x instanceof String s)で確認とキャストを組み合わせられます
  • Java 21のパターン対応switchでは、オプションのガードを使って型ごとに簡潔に振り分けられます
  • シールドクラスと網羅的なswitchを組み合わせると、defaultケースが不要になります

よくある質問

「instanceof 演算子」レッスンは無料ですか?

はい。「instanceof 演算子」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Java Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Java Academyコースには全4レッスンが含まれています。

「instanceof 演算子」で何を学びますか?

キャスト前に instanceof でオブジェクトの型を確認し、ClassCastException を回避します。 ブラウザで直接実行するハンズオンコードでJava Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Java Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのJava Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。

「instanceof 演算子」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このJava Academyレッスンでコードを書いて実行できますか?

はい。すべてのJava Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. プリミティブ型と参照型
  2. 拡大変換と縮小変換
  3. instanceof 演算子
  4. 型キャストの実践
← Java Academyに戻る