🖐️
アップキャストとダウンキャストを理解する
はじめに
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