Based on this oracle doc example I try create own example to test it. Of course referenced example work as suggested. But when I try base on Class.cast method I have a problem:
My code is
CL3 extends CL2 extends CL1 extends CL0 extends Base.
public class CL3 extends CL2 {
int x = 3;
public int getX() { return x; }
}
public class CL2 extends CL1 {
int x = 2;
public int getX() { return x; }
}
public class CL1 extends CL0 {
int x = 1;
public int getX() { return x; }
}
public class CL0 extends Base {
int x = 0;
public int getX() { return x; }
public String getPath() {
System.out.println("before obj : " + getClass().cast(this));
System.out.println("before class : " + getClass());
System.out.println("before x : " + getClass().cast(this).x);
System.out.println("before getX() : " + getClass().cast(this).getX());
System.out.println();
return getClazzPath(getClass());
}
}
public abstract class Base {
int x = -1;
abstract int getX();
@SuppressWarnings("unchecked")
public <T extends CL0> String getClazzPath(Class<T> clazz) {
System.out.println("clazz : " + clazz);
System.out.println("cast : " + clazz.cast(this));
System.out.println("cast.x : " + clazz.cast(this).x);
System.out.println("cast.getX() : " + clazz.cast(this).getX());
System.out.println("#");
return clazz.cast(this).x + (clazz == CL0.class ? "" : "/" + getClazzPath((Class<T>) clazz.getSuperclass()));
}
}
and the main function code is:
public static void main(String[] args) {
CL3 cl3 = new CL3();
System.out.println("cl3.getX()=" + cl3.getX());
System.out.println("((CL2)cl3).getX()=" + ((CL2) cl3).getX());
System.out.println("((CL1)cl3).getX()=" + ((CL1) cl3).getX());
System.out.println("((CL0)cl3).getX()=" + ((CL0) cl3).getX());
System.out.println("((IdentyfiedScope)cl3).getX()=" + ((Base) cl3).getX());
System.out.println();
System.out.println("cl3.x=" + cl3.x);
System.out.println("((CL2)cl3).x=" + ((CL2) cl3).x);
System.out.println("((CL1)cl3).x=" + ((CL1) cl3).x);
System.out.println("((CL0)cl3).x=" + ((CL0) cl3).x);
System.out.println("((IdentyfiedScope)cl3).x=" + ((Base) cl3).x);
System.out.println();
System.out.println(cl3.getPath());
}
the output is:
cl3.getX()=3
((CL2)cl3).getX()=3
((CL1)cl3).getX()=3
((CL0)cl3).getX()=3
((IdentyfiedScope)cl3).getX()=3
cl3.x=3
((CL2)cl3).x=2
((CL1)cl3).x=1
((CL0)cl3).x=0
((IdentyfiedScope)cl3).x=-1
before obj : test.code.hierarchy.read.CL3@70dea4e
before class : class test.code.hierarchy.read.CL3
before x : 0
before getX() : 3
clazz : class test.code.hierarchy.read.CL3
cast : test.code.hierarchy.read.CL3@70dea4e
cast.x : 0
cast.getX() : 3
#
clazz : class test.code.hierarchy.read.CL2
cast : test.code.hierarchy.read.CL3@70dea4e
cast.x : 0
cast.getX() : 3
#
clazz : class test.code.hierarchy.read.CL1
cast : test.code.hierarchy.read.CL3@70dea4e
cast.x : 0
cast.getX() : 3
#
clazz : class test.code.hierarchy.read.CL0
cast : test.code.hierarchy.read.CL3@70dea4e
cast.x : 0
cast.getX() : 3
#
0/0/0/0
And the question is - why when we use Class.cast (called by getPath().getClazzPath()) method we have different results than produced by cast operator when x field is accessed directly? As we see output from getClazzPath method ('clazz : ') return proper types CL3 -> CL2 -> CL1 -> CL0 but x always referenced to 0.
I discovered that this is connected with T type in getClazzPath method - but I don't know how explain it correctly.
If here is any expert who can explain why in my case the behavior is different between cast operator and Class.cast?