🖐️

アップキャストとダウンキャストを理解する

に公開

はじめに

Javaを学習していると、必ず出てくるのが
アップキャスト / ダウンキャスト という概念です。

  • なぜキャストが必要なのか?
  • なぜ実行時エラーになることがあるのか?
  • (B) a って結局なにをしているのか?

この記事では、
「型」と「実体(newしているもの)」の違い に注目して、
アップキャストとダウンキャストを整理します。


前提となるクラス

class A {
    void hello() {
        System.out.println("A");
    }
}

class B extends A {
    void hello() {
        System.out.println("B");
    }
}

## アップキャスト
```java
A a = new B();

これは アップキャスト です。
• 参照の型:A
• 実体(中身):B

なぜOKなのか?

B extends A なので、
B は必ず A として振る舞える

つまり、
「できることを制限して見ているだけ」 なので安全です。
キャスト不要
コンパイルエラーにならない
実行時エラーにもならない

ダウンキャスト

A a = new B();
B b = (B) a;

これは ダウンキャスト です。
• Aとして持っていた参照を
• Bとして扱い直す

なぜキャストが必要?
A 型のままでは、B にしかないメソッドは呼べない。

a.hello(); // OK(Aにもある)
// a.onlyB(); ← これは呼べない

ダウンキャストが危険な理由

A a = new A();
B b = (B) a; // 実行時例外

見た目はキャストしている
しかし 実体は new A()

つまり、
「Aなのに、Bだと言い張っている」
この状態で Java は実行時にチェックし、
嘘だと判断すると ClassCastException を投げる。

コンパイルエラーにならない理由

B b = (B) a;

このコードは 文法的には正しい ため、
コンパイルは通ります。

しかし、
実体が何かは実行時にならないと分からない。

そのためJavaは、実行時に安全確認を行う設計 になっています。

Discussion