What is upcasting and downcasting in the Java language?

Question:

What would downcasting and upcasting be in Java? Examples please.

Answer:

Upcasting is making an object impersonate an object that is a supertype of it. It will always work since every object is fully compatible with a type from which it was derived. As can always be done, it is possible to do it implicitly, that is, the compiler does it for you when necessary.

It is very common for it to occur as a parameter of a method that will use polymorphism. The caller sends an object that is the subtype as an argument, the method receives a parameter as if it were the supertype, but it works as a subtype. But note that polymorphism is an auxiliary mechanism and not directly linked to casting . It is considered a compile-time cast.

Some people like to call it a type promotion.

Downcasting is when the object is passed as if it were a subtype of it. There is no guarantee that it will work (it might throw a ClassCastException , which is obviously a programming error) and conversions might be required. The compiler only accepts it if it can prove that the object will fit perfectly and is in fact that object. So it must be explained by the programmer when he wants this action. Coercion takes place at runtime.

Some people like to call it type demo (although it's a neologism).

There is a commonly used pattern to avoid the exception when you are not sure it will work:

obj instanceof Tipo ? (Tipo)obj : null

In this example if the object is not the proper type, it will create a null and not even attempt to cast . Obviously, any attempt to access the generated object will be problematic, so it is necessary to check if the object is null before trying to access it, otherwise, it will only change error.

Examples:

class Animal { 
    public void fazBarulho() {
        System.out.println("silêncio");
    }
}
class Dog extends Animal { 
    public void fazBarulho() {
        System.out.println("au au");
    }
}
class Cat extends Animal { 
    public void fazBarulho() {
        System.out.println("miau");
    }
}
class Ideone {
    public static void main(String[] args) {
        Dog dog = new Dog();      
        Animal animal = new Animal();
        Animal animal2 = new Dog();
        Animal animal3 = new Cat();
        dog.fazBarulho();
        animal.fazBarulho();
        animal2.fazBarulho(); //concretamente é um cachorro
        animal3.fazBarulho(); //concretamente é um gato
        System.out.println("-- Castings agora --");
        ((Animal)dog).fazBarulho(); //upcasting
        ((Dog)animal2).fazBarulho(); //downcasting, funciona
        ((Dog)animal3).fazBarulho(); //downcasting, dá erro porque um gato não é um cachorro
        ((Dog)animal).fazBarulho(); //downcasting, dá erro aqui
    }
}

See "working" in ideone . And on repl.it. Also posted on GitHub for future reference .

When there are no guarantees that the object will have everything expected of that type, the cast will fail. It's the obvious case of a cat trying to impersonate a dog. When the generic animal tries to impersonate a dog, it doesn't work either. Although coincidentally in this example it might even work, the compiler cannot prove it. The programmer who is looking at all the code knows, but he may not always be able to see all the classes. What's more, it is possible for a maintenance to modify the class and what used to stop working. So you have to go the safe way.

In general this works the same in all languages ​​that have inheritance.

Scroll to Top