Arung Arung - 2 months ago 11
Java Question

What's the need to use Upcasting in java?

I've gone through most of the papers in the net, but I'm still not able to understand, why we have to use upcasting.

class Animal
public void callme()
System.out.println("In callme of Animal");

class Dog extends Animal
public void callme()
System.out.println("In callme of Dog");

public void callme2()
System.out.println("In callme2 of Dog");

public class UseAnimlas
public static void main (String [] args)
Dog d = new Dog();
Animal a = (Animal)d;
((Dog) a).callme2();

You can consider this example for upcasting. What's the use of upcasting here? Both
giving the same output!


In most situations, an explicit upcast is entirely unnecessary and has no effect.

In your example, the explicit upcast

    Animal a = (Animal)d;

could be replaced with this:

    Animal a = d;    // implicit upcast

The purpose of an implicit upcast (for a Java object type) is to "forget" static type information so that an object with a specific type can be used in a situation that requires a more general type. This affects compile-time type checking, not runtime behavior.

(For a primitive type, an upcast results in a conversion, and can in some cases result in loss of precision; e.g. long -> float.)

However, there are situations where the presence of an explicit upcast changes the meaning of the statement / expression.

One situation where it is necessary to use upcasting in Java is when you want to force a specific method override to be used; e.g. suppose that we have overloaded methods:

public void doIt(Object o)...
public void doIt(String s)...

If I have a String and I want to call the first overload rather than the second, I have to do this:

String arg = ...

doIt((Object) arg);

A related case is:

doIt((Object) null);

where the code won't compile without the type cast. (I'm not sure if this counts as an upcast, but here it is anyway.)

A second situation involves varadic parameters:

public void doIt(Object... args)...

Object[] foo = ...

doIt(foo);  // passes foo as the argument array
doIt((Object) foo); // passes new Object[]{foo} as the argument array.

A third situation is when performing operations on primitive numeric types; e.g.

int i1 = ...
int i2 = ...
long res = i1 + i2;           // 32 bit signed arithmetic ... might overflow
long res2 = ((long) i1) + i2; // 64 bit signed arithmetic ... won't overflow