What's the need to use Upcasting in java?

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 and overload resolution, but not run-time 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 overload 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 (see JLS 5.1.13 last paragraph) but it should be mentioned 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

What's the need to use Upcasting in java?

Not sure if you got the terminology right, but here is a quote to clarify:

upcasting
Doing a cast from a derived class to a more general base class.

And here's one scenario where it actually matters:

class A {
}

class B extends A {
}

public class Test {

    static void method(A a) {
        System.out.println("Method A");
    }

    static void method(B b) {
        System.out.println("Method B");
    }

    public static void main(String[] args) {
        B b = new B();
        method(b);                      // "Method B"

        // upcasting a B into an A:
        method((A) b);                  // "Method A"
    }
}

Another more subtle situation (related to access modifiers) is described here: Java Oddity: How an upcast can save the day


Upcasting has absolutely no meaning in your example (in fact I can't imagine any case where it has any) and should be avoided as it only confuses developers. Some IDEs (IntelliJ for sure) will issue a warning in this line and suggest removing upcasting).

EDIT: This code gives the same results because all object methods in Java are virtual, which means the target method is discovered by the actual type of the object at runtime rather than by reference type. Try making callme() static and see what happens.

Tags:

Java