次の例を見てください
public class Animal
{
public void eat(){}
}
public class Dog extends Animal
{
public void eat(){}
public void main(String[] args)
{
Animal animal=new Animal();
Dog dog=(Dog) animal; //will not work
}
}
キャストを使用することで、本質的にコンパイラーに「私を信じてください。私はプロであり、自分が何をしているのかを知っています。保証はできませんが、この動物変数は間違いなく犬になります。」
動物は実際には犬ではないため (動物なので、 Animal animal = new Dog(); を実行すると犬になります)、VM は実行時に例外をスローします。これは、その信頼に違反したためです (コンパイラはすべて問題ありませんが、そうではありません!)
コンパイラは、盲目的にすべてを受け入れるよりも少し賢く、異なる継承階層でオブジェクトをキャストしようとすると (たとえば、Dog を文字列にキャストする)、コンパイラはそれをスローします。
基本的には、コンパイラが不平を言うのを止めているだけなので、キャストするたびに、if ステートメントで instanceof を使用して ClassCastException を発生させないことを確認することが重要です (またはそのような効果があります)。
あなたの場合、私の参照 b がポイント B のオブジェクトを指していると言っているので、クラス A のオブジェクトを指すようにします (これは、参照 b が期待していたクラス B のオブジェクトではありません)。したがって、classCastException が発生します。
次のようなことができます
A a = new B();
B b = (B) a;