Perhaps in your daily Java coding, you see (and use) upcasting and downcasting occasionally. You may hear the terms ‘casting’, ‘upcasting’, ‘downcasting’ from someone or somewhere, and you may be confused about them.

As you read on, you will realize that upcasting and downcasting are really simple.

Before we go into the details, suppose that we have the following class hierarchy:

      Mammal > Animal > Dog, Cat

 

Mammal is the super interface:

public interface Mammal {
	public void eat();

	public void move();

	public void sleep();
}

Animal is the abstract class:

public abstract class Animal implements Mammal {
	public void eat() {
		System.out.println("Eating...");
	}

	public void move() {
		System.out.println("Moving...");
	}

	public void sleep() {
		System.out.println("Sleeping...");
	}

}

Dog and Cat are the two concrete sub classes:

public class Dog extends Animal {
	public void bark() {
		System.out.println("Gow gow!");
	}
	public void eat() {
		System.out.println("Dog is eating...");
	}
}

public class Cat extends Animal {
	public void meow() {
		System.out.println("Meow Meow!");
	}
}

 

1. What is Upcasting in Java?

Upcasting is casting a subtype to a supertype, upward to the inheritance tree. Let’s see an example:

Dog dog = new Dog();
Animal anim = (Animal) dog;
anim.eat();

Here, we cast the Dog type to the Animal type. Because Animal is the supertype of Dog, this casting is called upcasting.

Note that the actual object type does not change because of casting. The Dog object is still a Dog object. Only the reference type gets changed. Hence the above code produces the following output:

Dog is eating…

Upcasting is always safe, as we treat a type to a more general one. In the above example, an Animal has all behaviors of a Dog.

This is also another example of upcasting:

Mammal mam = new Cat();
Animal anim = new Dog();

 

2. Why is Upcasting in Java?

Generally, upcasting is not necessary. However, we need upcasting when we want to write general code that deals with only the supertype. Consider the following class:

public class AnimalTrainer {
	public void teach(Animal anim) {
		anim.move();
		anim.eat();
	}
}

Here, the teach() method can accept any object which is subtype of Animal. So objects of type Dog and Cat will be upcasted to Animal when they are passed into this method:

Dog dog = new Dog();
Cat cat = new Cat();

AnimalTrainer trainer = new AnimalTrainer();
trainer.teach(dog);
trainer.teach(cat);

 

3. What is Downcasting in Java?

Downcasting is casting to a subtype, downward to the inheritance tree. Let’s see an example:

Animal anim = new Cat();
Cat cat = (Cat) anim;

Here, we cast the Animal type to the Cat type. As Cat is subclass of Animal, this casting is called downcasting.

Unlike upcasting, downcasting can fail if the actual object type is not the target object type. For example:

Animal anim = new Cat();
Dog dog = (Dog) anim;

This will throw a ClassCastException because the actual object type is Cat. And a Cat is not a Dog so we cannot cast it to a Dog.

The Java language provides the instanceof keyword to check type of an object before casting. For example:

if (anim instanceof Cat) {
	Cat cat = (Cat) anim;
	cat.meow();
} else if (anim instanceof Dog) {
	Dog dog = (Dog) anim;
	dog.bark();
}

So if you are not sure about the original object type, use the instanceof operator to check the type before casting. This eliminates the risk of a ClassCastException thrown.

 

4. Why is Downcasting in Java?

Downcasting is used more frequently than upcasting. Use downcasting when we want to access specific behaviors of a subtype.

Consider the following example:

public class AnimalTrainer {
	public void teach(Animal anim) {
		// do animal-things
		anim.move();
		anim.eat();

		// if there's a dog, tell it barks
		if (anim instanceof Dog) {
			Dog dog = (Dog) anim;
			dog.bark();
		}
	}
}

Here, in the teach() method, we check if there is an instance of a Dog object passed in, downcast it to the Dog type and invoke its specific method, bark().

Okay, so far you have got the nuts and bolts of upcasting and downcasting in Java. Remember:

  • Casting does not change the actual object type. Only the reference type gets changed.
  • Upcasting is always safe and never fails.
  • Downcasting can risk throwing a ClassCastException, so the instanceof operator is used to check type before casting.

That’s all for upcasting and downcasting today.

 

Other Recommended Tutorials:


About the Author:

is certified Java programmer (SCJP and SCWCD). He began programming with Java back in the days of Java 1.4 and has been passionate about it ever since. You can connect with him on Facebook and watch his Java videos on YouTube.



Add comment

   


Comments 

#10rathinavelu2022-02-18 03:51
Dog dog = new Dog();
Animal anim = dog; //Enough
anim.eat(); // fails if eat() is not overridden. Try!!
two references anim and dog, are there now. reference does not 'change'.
Entire article is absolute trash!
Quote
#9Pushkal Shandilya2021-04-23 06:40
The Cat and Dog class below implement the Animal interface. All animals have names, but only dogs do tricks. Implement the describe method, using the instanceof operator to test whether the given animal is a dog. If so, return the name, a space, and the trick that the dog can do, such as "Helmut barks at the moon". If it is any other kind of animal, return the name, a space, and "has no tricks".
Quote
#8Nam2020-03-30 23:20
Chào Duc,
Downcasting được dùng thường xuyên em ạ. Phổ biến trong hàm equals(). Em xem ví dụ ở bài viết này: codejava.net/.../...
Quote
#7Duc2020-03-26 23:40
Đọc qua bài của anh em vẫn chưa hiểu tại sao lại phải cần sử dụng downcasting? Tại sao không sử dụng luôn upcasting đi?

Nếu được anh có thể cho em một vài ví dụ cụ thể không?

Thanks anh
Quote
#6Iain Logician2018-10-24 15:34
Your example is illogical - if you're going to use real-world examples, the words have meanings. All mammals are animals, but not all animals are mammals. You should start with Animal > Mammal > Dog.
Quote