ClassCastException の原因と直し方
キャストは宣言にすぎず、実体が違えば実行時に落ちます。instanceofによる事前確認を扱います。
エラーメッセージの読み方
Main.java:4: error: incompatible types: String cannot be converted to Integer
Main.java- ファイル名
4- 行番号 — javacが異常に気づいた位置。原因の行とは限りません
error- 種別 — コンパイルエラー。実行まで到達しません
incompatible types: String cannot be converted to Integer- 内容 — javacが期待していたもの、または見つけられなかったもの
このエラーが出る典型パターン
パターン1
1 public class Main { 2 public static void main(String[] args) { 3 Object o = "java"; 4 Integer s = (String) o; ^ 5 System.out.println(s); 6 } 7 }
Main.java:4: error: incompatible types: String cannot be converted to Integer
キャストの結果の型と受け取る変数の型は一致させます。ここはコンパイル時に検出できます。
直し方: Integer を String にします。
広告
広告スロット(未設定)
パターン2
1 public class Main { 2 public static void main(String[] args) { 3 Object o = "java"; 4 Integer n = (Integer) o; ^ 5 System.out.println(n); 6 } 7 }
Exception in thread "main" java.lang.ClassCastException:
class java.lang.String cannot be cast to class java.lang.Integerexited with code 1
キャストは「そう扱う」という宣言にすぎません。実体が違えば実行時に落ちます。instanceofで事前に確認します。
直し方: Integer を Integer にします。
パターン3
1 public class Main { 2 public static void main(String[] args) { 3 Object o = "java"; 4 if (o is String) { ^ 5 System.out.println(((String) o).length()); 6 } 7 } 8 }
Main.java:4: error: ')' expected
型を確認する演算子はinstanceofです。キャストの前に挟むとClassCastExceptionを防げます。
直し方: is を instanceof にします。
よくある誤解
コンパイルが通ったキャストほど危険です。javacは「あり得るかどうか」しか見ておらず、実際の中身は知りません。
まとめ
ClassCastExceptionは中級でつまずきやすい項目です。上の3パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。