はじめに
今回は、Javaでよく遭遇する例外のひとつ。「java.lang.ClassCastException」について記載していきたいと思います。
他にも、体系的にJavaを学びたい方には以下の教材がおすすめです:
👉スッキリわかるJava入門
👉スッキリわかるJava入門 実践編
ClassCastExceptionとは
ClassCastExceptionとは、「互換性のない型にキャスト(変換)しようとしたときに発生する例外」です。
例
StringはIntegerに変換できないためエラーになります。
Object obj = "Hello World";
Integer num = (Integer) obj; // ここでエラー
java.lang.ClassCastException: class java.lang.String cannot be cast to class java.lang.Integer
なぜ発生するのか
ClassCastExceptionの原因はシンプルで、見た目の型と実際の型を勘違いして、キャストした際に発生します。「文字列」思ってキャストしたら違ったというのが発生する主な原因です。
よくある原因と対策
1.キャストミス
戻り値の型が曖昧な「Object」に対して、呼び出し側が勝手に決めつけて型変換をかけるとExceptionが発生します。
Object data = getData();
// 実はStringなのに
Integer num = (Integer) data;
対策:instanceofで確認
キャストする前に明示的に型チェックを実施するとエラーを防ぐことができます。
Object obj = getData();
if (obj instanceof Integer) {
Integer num = (Integer) obj;
}
ListやMapの型ミス(ジェネリクス未使用)
ジェネリクス未使用で型が確定していない変数は、中にどの型の値が入っているかわからないため、安全にキャストすることができません。
List list = new ArrayList();
list.add("test");
Integer num = (Integer) list.get(0); // エラー
対策:ジェネリクスを使う
ジェネリクスを使用し、型なしListは使わない用にしましょう。ジェネリクスはを指定すれば、キャスト時に間違った指定をしていた場合、コンパイルのタイミングで防ぐことができます。
List<String> list = new ArrayList<>();
list.add("Hello");
// コンパイル時に防げる
String str = list.get(0);
継承・インターフェースの誤解
親クラスの型だからといって、子クラスの型に戻せるとは限らないという誤解から生まれるキャストのエラーとなります。
class Animal {}
class Dog extends Animal {}
class Cat extends Animal {}
Animal animal = new Cat();
Dog dog = (Dog) animal; // ←ここでエラー
対策:正しく型を継承を理解
実体のクラスを正しく理解し、変換を行うこと。
Animal animal = new Dog(); // 実体がDog
Dog dog = (Dog) animal; // OK
まとめ
ClassCastExceptionは、「型の認識ミスによって発生する例外」です。問題を解決するために以下を心がけましょう。
- 実際の型を確認する
- キャスト前にチェックする
- 設計を見直す
ドキュメント
【公式ドキュメント】
Java SE Specifications (oracle.com)
最後に
Javaの環境構築は、この記事を参照してみてください。
【開発環境構築】VS CodeでJavaを使用するための環境構築を実施する – SEもりのLog (selifemorizo.com)
以上、ログになります。
これからも継続していきましょう!!


コメント