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;
}
}
The assignment Dog dog = (Dog) animal;
does not generate a compilation error, but at runtime it generates a ClassCastException
. Why can't the compiler detect this error?
By using a cast you're essentially telling the compiler "trust me. I'm a professional, I know what I'm doing and I know that although you can't guarantee it, I'm telling you that this animal
variable is definitely going to be a dog."
Since the animal isn't actually a dog (it's an animal, you could do Animal animal = new Dog();
and it'd be a dog) the VM throws an exception at runtime because you've violated that trust (you told the compiler everything would be ok and it's not!)
The compiler is a bit smarter than just blindly accepting everything, if you try and cast objects in different inheritence hierarchies (cast a Dog to a String for example) then the compiler will throw it back at you because it knows that could never possibly work.
Because you're essentially just stopping the compiler from complaining, every time you cast it's important to check that you won't cause a ClassCastException
by using instanceof
in an if statement (or something to that effect.)