web-dev-qa-db-ja.com

Javaの「ClassCastException」の説明

「ClassCastException」について書かれた記事をいくつか読みましたが、それについて良いアイデアを得ることができませんでした。良い記事がありますか、または簡単な説明は何ですか?

ClassCastException のAPI仕様から直接:

コードがオブジェクトをインスタンスではないサブクラスにキャストしようとしたことを示すためにスローされます。

そのため、たとえば、IntegerStringにキャストしようとすると、StringIntegerのサブクラスではないため、ClassCastExceptionがスローされます。

Object i = Integer.valueOf(42);
String s = (String)i;            // ClassCastException thrown here.
105
coobird

クラスAのオブジェクトをクラスBのオブジェクトに型キャストしようとしていて、それらに互換性がない場合、クラスキャスト例外が発生します。

クラスのコレクションを考えてみましょう。

class A {...}
class B extends A {...}
class C extends A {...}
  1. すべてのJavaクラスはObjectを継承するため、これらのオブジェクトをObjectにキャストできます。
  2. BまたはCをAにキャストできます。どちらもAの「種類」なので
  3. Aオブジェクトへの参照をBにキャストできます場合のみ実際のオブジェクトはBです。
  4. 両方がAであっても、BをCにキャストすることはできません。
76
Charlie Martin

クラスをダウンキャストしようとした場合に発生する例外ですが、実際にはクラスはそのタイプではありません。

この階層を検討してください。

オブジェクト->動物->犬

次のメソッドがあります:

 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
 }
20
Yishai

例を考えてみましょう、

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の対処方法:

  1. クラスのオブジェクトを別のクラスにキャストしようとするときは注意してください。新しいタイプがその親クラスの1つに属していることを確認してください。
  2. Genericsはコンパイル時のチェックを提供し、タイプセーフなアプリケーションの開発に使用できるため、Genericsを使用してClassCastExceptionを防ぐことができます。

音符と休符のソース

9

キャストの概念を理解していますか?キャストは型変換のプロセスであり、静的に型付けされた言語であるため、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.
4
Mork0075

オブジェクトを、そうでないクラスのインスタンスとして処理しようとしています。これは、ギターのダンパーペダルを押すのとほぼ同じです(ピアノにはダンパーペダルがありますが、ギターにはありません)。

4
Jeremy Huiskamp

あるデータ型のオブジェクトを別のデータ型にキャストしようとすると、Javaによってクラスキャスト例外がスローされます。

Javaでは、互換性のあるデータ型間でキャストが行われる限り、ある型の変数を別の型にキャストできます。

たとえば、文字列をオブジェクトとしてキャストできます。同様に、文字列値を含むオブジェクトを文字列にキャストできます。

多数のArrayListオブジェクトを保持するHashMapがあると仮定します。

このようなコードを書くと:

String obj = (String) hmp.get(key);

ハッシュマップのgetメソッドによって返される値は配列リストになるため、クラスキャスト例外がスローされますが、文字列にキャストしようとしています。これにより、例外が発生します。

3
shakun tyagi

Javaのc​​lasscastExceptionについて説明できる非常に良い例は、「コレクション」の使用中です。

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になります。

2
Mistriel

オブジェクトをソートしたいが、クラスが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にキャストできません

0
karepu

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がスローされます。

0