0

I have upcasted Model2 instance in the following code to Object class and then downcasted back to the class - Model2 in the test method of Model1 class. But thenUov its attribute value after downcasting is showing null. Is this expected for the instance to loose its state after Upcasting-then-Downcasting? Could you please share some details for the same. Also, is there a way to retain the state of the instance after upcasting?

public class Demo{

    public static void main(String[] args) {
        Model1 m1 = new Model1();
        m1.setAttr1(10);

        Model2 m2 = new Model2();
        m2.setAttr2(10);

        m1.test(m2);
    }

}


class Model1 {

    private Integer attr1;

    public Integer getAttr1() {
        return attr1;
    }

    public void setAttr1(Integer attr1) {
        this.attr1 = attr1;
    }

    public void test(Object o) {
        Model2 m = (Model2) o;
        System.out.println(m.getAttr2());
    }

}

class Model2 {

    private Integer attr2;

    public Integer getAttr2() {
        return attr2;
    }

    public void setAttr2(Integer attr1) {
        this.attr2 = attr2;
    }
}
R.J. Dunnill
  • 2,049
  • 3
  • 10
  • 21
user93726
  • 683
  • 1
  • 9
  • 22

2 Answers2

7

No, you don't lose data when casting - an Object is the Object it is.

You are getting null due to a typo in Model2

public void setAttr2(Integer attr1) {
        this.attr2 = attr2;
}

You are setting attr2 to itself, the function definition should be (Interger attr2)

Changing that will output 10

CeePlusPlus
  • 803
  • 1
  • 7
  • 26
1

Casting doesn't loose any information in Java, it simply changes the level of abstraction (i.e you can't access method getAttr2() on 'o' whilst it is still cast as an object)

The real problem is a typo in model2. You are setting the variable 'attr2' to itself, which is set to null to start with

You want it to be this.attr2 = attr1


I realise that this is probably just a test class, but I would like to also point out that it's good practise to check your argument before casting it - you could have been passed a null or an object of the wrong type.

public void test(Object o) {
    if (o == null) {
        System.out.println("Don't give me a null");
    } else if (o instanceof Model2) {
        Model2 m = (Model2) o;
        System.out.println(m.getAttr2());
    } else {
        System.out.println("Wrong type. Was given " + o.getClass());
    }
}

In a real class you'd actually do something useful in those sections such as throw an exception

user27158
  • 297
  • 1
  • 5