Downcasting in Java

后端 未结 11 2121
自闭症患者
自闭症患者 2020-11-22 03:15

Upcasting is allowed in Java, however downcasting gives a compile error.

The compile error can be removed by adding a cast but would anyway break at the runtime.

相关标签:
11条回答
  • 2020-11-22 03:34

    @ Original Poster - see inline comments.

    public class demo 
    {
        public static void main(String a[]) 
        {
            B b = (B) new A(); // compiles with the cast, but runtime exception - java.lang.ClassCastException 
            //- A subclass variable cannot hold a reference to a superclass  variable. so, the above statement will not work.
    
            //For downcast, what you need is a superclass ref containing a subclass object.
            A superClassRef = new B();//just for the sake of illustration
            B subClassRef = (B)superClassRef; // Valid downcast. 
        }
    }
    
    class A 
    {
        public void draw() 
        {
            System.out.println("1");
        }
    
        public void draw1() 
        {
            System.out.println("2");
        }
    }
    
    class B extends A 
    {
        public void draw() 
        {
            System.out.println("3");
        }
    
        public void draw2() 
        {
            System.out.println("4");
        }
    }
    
    0 讨论(0)
  • 2020-11-22 03:35

    Downcasting is allowed when there is a possibility that it succeeds at run time:

    Object o = getSomeObject(),
    String s = (String) o; // this is allowed because o could reference a String
    

    In some cases this will not succeed:

    Object o = new Object();
    String s = (String) o; // this will fail at runtime, because o doesn't reference a String
    

    When a cast (such as this last one) fails at runtime a ClassCastException will be thrown.

    In other cases it will work:

    Object o = "a String";
    String s = (String) o; // this will work, since o references a String
    

    Note that some casts will be disallowed at compile time, because they will never succeed at all:

    Integer i = getSomeInteger();
    String s = (String) i; // the compiler will not allow this, since i can never reference a String.
    
    0 讨论(0)
  • 2020-11-22 03:35

    Consider the below example

    public class ClastingDemo {
    
    /**
     * @param args
     */
    public static void main(String[] args) {
        AOne obj = new Bone();
        ((Bone) obj).method2();
    }
    }
    
    class AOne {
    public void method1() {
        System.out.println("this is superclass");
    }
    }
    
    
     class Bone extends AOne {
    
    public void method2() {
        System.out.println("this is subclass");
    }
    }
    

    here we create the object of subclass Bone and assigned it to super class AOne reference and now superclass reference does not know about the method method2 in the subclass i.e Bone during compile time.therefore we need to downcast this reference of superclass to subclass reference so as the resultant reference can know about the presence of methods in the subclass i.e Bone

    0 讨论(0)
  • 2020-11-22 03:37

    Downcast works in the case when we are dealing with an upcasted object. Upcasting:

    int intValue = 10;
    Object objValue = (Object) intvalue;
    

    So now this objValue variable can always be downcasted to int because the object which was cast is an Integer,

    int oldIntValue = (Integer) objValue;
    // can be done 
    

    but because objValue is an Object it cannot be cast to String because int cannot be cast to String.

    0 讨论(0)
  • 2020-11-22 03:47

    I believe this applies to all statically typed languages:

    String s = "some string";
    Object o = s; // ok
    String x = o; // gives compile-time error, o is not neccessarily a string
    String x = (String)o; // ok compile-time, but might give a runtime exception if o is not infact a String
    

    The typecast effectively says: assume this is a reference to the cast class and use it as such. Now, lets say o is really an Integer, assuming this is a String makes no sense and will give unexpected results, thus there needs to be a runtime check and an exception to notify the runtime environment that something is wrong.

    In practical use, you can write code working on a more general class, but cast it to a subclass if you know what subclass it is and need to treat it as such. A typical example is overriding Object.equals(). Assume we have a class for Car:

    @Override
    boolean equals(Object o) {
        if(!(o instanceof Car)) return false;
        Car other = (Car)o;
        // compare this to other and return
    }
    
    0 讨论(0)
提交回复
热议问题