キャストの罠

キャストの罠

このレッスンでできるようになること。ダウンキャストがコンパイルを通るのに実行時に落ちる場面を、あらかじめ見抜けるようになります。

親型から子型へ変換することをダウンキャストと呼びます。逆のアップキャストは安全なので何も書かずに通りますが、ダウンキャストは書き手が保証する形になります。

class Animal {} class Dog extends Animal {} class Cat extends Animal {} Animal a = new Cat(); Dog d = (Dog) a;

この2行はコンパイルを通ります。a の宣言型は Animal で、DogAnimal の子なので、コンパイラは中身が Dog である可能性を否定できないからです。しかし実行すると ClassCastException が投げられます。中身は Cat であって Dog ではないからです。

コンパイルエラーになるのはどんなときか

継承の線でまったくつながっていない型どうしのキャストは、コンパイルの時点で弾かれます。DogCat は兄弟なので、Dog d = (Dog) new Cat(); と直接書けばコンパイルエラーです。いったん Animal 型の変数に入れると、コンパイラの目には可能性が残るので通ってしまい、実行時まで問題が先送りされます。この差が試験でよく問われます。

落ちる前に確かめる

安全に書きたいときは instanceof で中身を確かめてからキャストします。a instanceof Dogtrue のときだけキャストすれば、例外は起きません。なお null に対するキャストはいつでも成功し、例外にはなりません。nullinstanceof で調べると必ず false になる点と合わせて覚えておくと迷いません。

演習では、例外の名前を実際に取り出して確かめます。例外のクラス名は e.getClass().getSimpleName() で取れます。

要件

  1. 変数の宣言型は Animal にする
  2. trycatch で例外を受け止める
  3. 例外時は e.getClass().getSimpleName() を返す

入出力例

tryCast(1)"Dog" tryCast(2)"ClassCastException"

ヒント

生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア
編集 LuaGate編集部
main.java
学習モード

メモ

キャストの罠

⌘S で保存