Michael Berry tarafından verilen cevabı detaylandırarak.
Dog d = (Dog)Animal; //Compiles but fails at runtime
Burada derleyici diyorsun ki "Güven bana. Biliyorum d
bir Dog
nesneye gerçekten atıfta bulunuyor" ama olmasa da.
Unutmayın derleyici bir mahzun yaparken bize güvenmek zorunda .
Derleyici yalnızca bildirilen başvuru türünü bilir. Çalışma zamanında JVM, nesnenin gerçekte ne olduğunu bilir.
Öyleyse, çalışma zamanında JVM Dog d
, aslında Animal
bir Dog
nesneye değil bir nesneye atıfta bulunduğunu anladığında diyor. Hey ... derleyiciye yalan söyledin ve büyük bir yağ atıyorsun ClassCastException
.
Bu yüzden aşağı iniş yapıyorsanız, instanceof
vidalanmayı önlemek için test kullanmalısınız .
if (animal instanceof Dog) {
Dog dog = (Dog) animal;
}
Şimdi aklımıza bir soru geliyor. Cehennem derleyicisi nihayet bir atmak için mahzun izin veriyor java.lang.ClassCastException
?
Cevap, derleyicinin yapabileceği, iki türün aynı miras ağacında olduğunu doğrulamaktır, bu nedenle, downcast'ten önce hangi kodun gelebileceğine bağlı olarak animal
, türün olması mümkündür dog
.
Derleyici, çalışma zamanında mümkün olabilecek şeylere izin vermelidir.
Aşağıdaki kod snipet'ini düşünün:
public static void main(String[] args)
{
Dog d = getMeAnAnimal();// ERROR: Type mismatch: cannot convert Animal to Dog
Dog d = (Dog)getMeAnAnimal(); // Downcast works fine. No ClassCastException :)
d.eat();
}
private static Animal getMeAnAnimal()
{
Animal animal = new Dog();
return animal;
}
Ancak, derleyici, almanın mümkün olmayacağından emin olursa, derleme başarısız olur. IE Farklı miras hiyerarşilerinde nesneler yayınlamaya çalışırsanız
String s = (String)d; // ERROR : cannot cast for Dog to String
Alt sürümün tersine, üst sürüm, örtük olarak çalışır, çünkü üst üste çıkardığınızda, alt sürümün tersine çağırabileceğiniz yöntem sayısını dolaylı olarak kısıtlarsınız; bu, daha sonra daha spesifik bir yöntem çağırmak isteyebileceğiniz anlamına gelir.
Dog d = new Dog();
Animal animal1 = d; // Works fine with no explicit cast
Animal animal2 = (Animal) d; // Works fine with n explicit cast
Yukarıdaki upcast her ikisi de istisnasız iyi çalışacaktır, çünkü bir Hayvan IS, bir Hayvan yapabilirsiniz anithing, bir köpek yapabilirsiniz. Ama bu tam tersi değil.