简体   繁体   中英

Upcasting and Downcasting in java

I can understand what upcasting is but Downcasting is a little confusing. My question is why should we downcast? Can you help me with a real time example ? Is downcasting that important?

Downcasting is a necessary evil, for example when dealing with legacy APIs that return non-generic collections. Another classic example is an equals method:

public class Phleem{

    public Phleem(final String phloom){
        if(phloom == null){
            throw new NullPointerException();
        }
        this.phloom = phloom;
    }

    private final String phloom;

    public String getPhloom(){
        return phloom;
    }

    @Override
    public boolean equals(final Object obj){
        if(obj instanceof Phleem){
            // downcast here
            final Phleem other = (Phleem) obj;
            return other.phloom.equals(phloom);
        }
        return false;
    }

    // ...

}

I can't think of an example where Upcasting is necessary though. OK, it's good practice to return the least specific possible Object from a method, but that can be done entirely without casting:

public Collection<String> doStuff(){
    // no casting needed
    return new LinkedHashSet<String>();
}

To access the header methods of of the ServletResponse in a filter, you have to downcast to to an HttpServletResponse.

It's good to declare objects by the class they extend, so you can change the implementation on the fly. However if you need to access any of the methods that are specific to the implementation, you need to downcast.

What You need to remember is that downcasting is allowed when there is a possibility that it suceeds at run time.

This will work:

Object o = doStaff();
String s = (String) o; 

This will fail:

Object o = new Object();
String s = (String) s;

Q1: Why we should use downcast ?

It is generally up to developer, to used the downcast. Sometimes methods return Objects or use as parameter like equal method and then using subcast we can back to specific type.

Q2: Is downcast important ?

As everything in coding, but better word would be useful, IMHO it is.

The best solution for your question is to read a good book. You will learn about polymorphism, objects, patterns ...
Good start is "Beginning java objects 2nd edition"

Downcasting is needed when you receive an object that you know has some more specific (down the class hierarchy) type and you want to cast it to that type.

Example: you receive Object from some service and you know that it is actually String and you downcast it to String. Before downcasting you should always check the type otherwise you risk the ClassCastException:

Object receivedObject = receiveFromSomewhere();
if(receivedObject instanceof String){
    receivedString = (String) receivedObject;
}

Downcasting Example

//: RTTI.java
// Downcasting & Run-Time Type
// Identification (RTTI)
import java.util.*;

class Useful {
  public void f() {}
  public void g() {}
}

class MoreUseful extends Useful {
  public void f() {}
  public void g() {}
  public void u() {}
  public void v() {}
  public void w() {}
}

public class RTTI {
  public static void main(String[] args) {
    Useful[] x = {
      new Useful(),
      new MoreUseful()
    };
    x[0].f();
    x[1].g();
    // Compile-time: method not found in Useful:
    //! x[1].u();
    ((MoreUseful)x[1]).u(); // Downcast/RTTI
    ((MoreUseful)x[0]).u(); // Exception thrown
  }
} ///:~ 

Check source link for more information.

With the introduction of generics, it is less important than it was before, but there are times when you need it.

For instance, when you read an object from an ObjectInputStream.

One place you need it is if you override the equals method inherited from Object . Since the parameter passed to the method is of type Object , you have to cast it to the type of the class to be able to access methods and variables defined in it . Just pay special attention to what referred to object is. That is to say, instantiated object is passed to the equals() method, not its reference.

class MySuperClass
{
    private int num1;

    public MySuperClass() {}

    public MySuperClass(int num1)
    {
        this.num1 = num1;
    }
}

class MySubClass extends MySuperClass
{
    private int num;

    public MySubClass(int num)
    {
        this.num = num;
    }

    public boolean equals(Object o)
    {
        if (!(o instanceof MySubClass))
            return false;

        MySubClass mySub = (MySubClass)o;

        return(mySub.num == num);
    }

    public static void main(String[] args)
    {
        Object mySub = new MySubClass(1);
        MySuperClass mySup = new MySubClass(1);

        System.out.println(mySub.equals(mySup));
    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM