「ClassCastException」について書かれた記事をいくつか読みましたが、それについて良いアイデアを得ることができませんでした。良い記事がありますか、または簡単な説明は何ですか?
ClassCastException
のAPI仕様から直接:
コードがオブジェクトをインスタンスではないサブクラスにキャストしようとしたことを示すためにスローされます。
そのため、たとえば、Integer
をString
にキャストしようとすると、String
はInteger
のサブクラスではないため、ClassCastException
がスローされます。
Object i = Integer.valueOf(42);
String s = (String)i; // ClassCastException thrown here.
クラスAのオブジェクトをクラスBのオブジェクトに型キャストしようとしていて、それらに互換性がない場合、クラスキャスト例外が発生します。
クラスのコレクションを考えてみましょう。
class A {...}
class B extends A {...}
class C extends A {...}
クラスをダウンキャストしようとした場合に発生する例外ですが、実際にはクラスはそのタイプではありません。
この階層を検討してください。
オブジェクト->動物->犬
次のメソッドがあります:
public void manipulate(Object o) {
Dog d = (Dog) o;
}
このコードで呼び出された場合:
Animal a = new Animal();
manipulate(a);
コンパイルは問題ありませんが、実行時にClassCastException
が返されます。これは、oが実際には犬ではなく動物であったためです。
Javaの以降のバージョンでは、以下を実行しない限り、コンパイラの警告が表示されます。
Dog d;
if(o instanceof Dog) {
d = (Dog) o;
} else {
//what you need to do if not
}
例を考えてみましょう、
class Animal {
public void eat(String str) {
System.out.println("Eating for grass");
}
}
class Goat extends Animal {
public void eat(String str) {
System.out.println("blank");
}
}
class Another extends Goat{
public void eat(String str) {
System.out.println("another");
}
}
public class InheritanceSample {
public static void main(String[] args) {
Animal a = new Animal();
Another t5 = (Another) new Goat();
}
}
Another t5 = (Another) new Goat()
:ClassCastException
を使用してAnother
クラスのインスタンスを作成できないため、Goat
を取得します。
注:変換は、クラスが親クラスを拡張し、子クラスがその親クラスにキャストされる場合にのみ有効です。
ClassCastException
の対処方法:
キャストの概念を理解していますか?キャストは型変換のプロセスであり、静的に型付けされた言語であるため、Javaで非常に一般的です。いくつかの例:
文字列 "1"をintにキャスト->問題なし
文字列 "abc"をintにキャスト-> ClassCastExceptionを発生させます
または、Animal.class、Dog.class、Cat.classを含むクラス図を考えてください
Animal a = new Dog();
Dog d = (Dog) a; // No problem, the type animal can be casted to a dog, because its a dog.
Cat c = (Dog) a; // Raises class cast exception; you can't cast a dog to a cat.
オブジェクトを、そうでないクラスのインスタンスとして処理しようとしています。これは、ギターのダンパーペダルを押すのとほぼ同じです(ピアノにはダンパーペダルがありますが、ギターにはありません)。
あるデータ型のオブジェクトを別のデータ型にキャストしようとすると、Javaによってクラスキャスト例外がスローされます。
Javaでは、互換性のあるデータ型間でキャストが行われる限り、ある型の変数を別の型にキャストできます。
たとえば、文字列をオブジェクトとしてキャストできます。同様に、文字列値を含むオブジェクトを文字列にキャストできます。
多数のArrayListオブジェクトを保持するHashMapがあると仮定します。
このようなコードを書くと:
String obj = (String) hmp.get(key);
ハッシュマップのgetメソッドによって返される値は配列リストになるため、クラスキャスト例外がスローされますが、文字列にキャストしようとしています。これにより、例外が発生します。
JavaのclasscastExceptionについて説明できる非常に良い例は、「コレクション」の使用中です。
List list = new ArrayList();
list.add("Java");
list.add(new Integer(5));
for(Object obj:list) {
String str = (String)obj;
}
上記のコードは、実行時にClassCastExceptionを提供します。整数を文字列にキャストしようとしているため、例外がスローされます。
JVMが不明を推測できないことに気付いたら、ClassCastExceptionとキャストをよりよく理解できます。 BがAのインスタンスである場合、ヒープにはAよりも多くのクラスメンバーとメソッドがあります。マッピングターゲットが大きいため、JVMはAをBにキャストする方法を推測できず、JVMは追加メンバーを埋める方法を知りません。
ただし、AがBのインスタンスである場合、AはBの完全なインスタンスへの参照であるため、マッピングが可能になるため、マッピングは1対1になります。
オブジェクトをソートしたいが、クラスがComparableまたはComparatorを実装しなかった場合、ClassCastExceptionが発生します。たとえば
class Animal{
int age;
String type;
public Animal(int age, String type){
this.age = age;
this.type = type;
}
}
public class MainCls{
public static void main(String[] args){
Animal[] arr = {new Animal(2, "Her"), new Animal(3,"Car")};
Arrays.sort(arr);
}
}
上記のメインメソッドはランタイムクラスキャスト例外をスローします
スレッド「メイン」の例外Java.lang.ClassCastException:com.default.AnimalをJava.lang.Comparableにキャストできません
Java ClassCastExceptionは、クラスをあるタイプから別のタイプに不適切に変換しようとしたときに発生する例外です。
import Java.util.ArrayList;
import Java.util.Iterator;
import Java.util.List;
public class ClassCastExceptionExample {
public ClassCastExceptionExample() {
List list = new ArrayList();
list.add("one");
list.add("two");
Iterator it = list.iterator();
while (it.hasNext()) {
// intentionally throw a ClassCastException by trying to cast a String to an
// Integer (technically this is casting an Object to an Integer, where the Object
// is really a reference to a String:
Integer i = (Integer)it.next();
}
}
public static void main(String[] args) {
new ClassCastExceptionExample();
}
}
このJavaプログラムを実行しようとすると、次のClassCastExceptionがスローされることがわかります。
Exception in thread "main" Java.lang.ClassCastException: Java.lang.String
at ClassCastExceptionExample (ClassCastExceptionExample.Java:15)
at ClassCastExceptionExample.main (ClassCastExceptionExample.Java:19)
ここで例外がスローされる理由は、リストオブジェクトを作成するとき、リストに格納するオブジェクトは文字列「1」ですが、後でこのオブジェクトを取得しようとすると、意図的にミスを犯すからです。整数にキャストします。 Stringを直接Integerにキャストできないため、IntegerはStringのタイプではないため、ClassCastExceptionがスローされます。