casting rel example

//X is a supper class of Y and Z which are sibblings.
public class RunTimeCastDemo {

      public static void main(String args[]) {
            X x = new X();
            Y y = new Y();
            Z z = new Z();
            X xy = new Y(); // compiles ok (up the hierarchy)
            X xz = new Z(); // compiles ok (up the hierarchy)
            //            Y yz = new Z();   incompatible type (siblings)
            //            Y y1 = new X();   X is not a Y
            //            Z z1 = new X();   X is not a Z
            X x1 = y; // compiles ok (y is subclass of X)
            X x2 = z; // compiles ok (z is subclass of X)
            Y y1 = (Y) x; // compiles ok but produces runtime error
            Z z1 = (Z) x; // compiles ok but produces runtime error
            Y y2 = (Y) x1; // compiles and runs ok (x1 is type Y)
            Z z2 = (Z) x2; // compiles and runs ok (x2 is type Z)
            //            Y y3 = (Y) z;     inconvertible types (siblings)
            //            Z z3 = (Z) y;     inconvertible types (siblings)
            Object o = z;
            Object o1 = (Y) o; // compiles ok but produces runtime error
      }
}      }
I was going through above example from link

http://www.javabeginner.com/learn-java/java-object-typecasting



I have not understood the output clearly.
I could not execute this program at all.

 Any ideas, resources,sample code,links,  highly appreciated. thanks in advance.



LVL 7
gudii9Asked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

theKashyapCommented:

Once you get the fundamentals it's a piece of cake..
Lets get some terminology right:
// In every assignment (x = y) you have 2 important types:
// real-type-of-RHS and variable-type-of-LHS.
X x1 = new X(); // variable type X, real type X
X x2 = new Y(); // variable type X, real type Y
// of course if you have a variable on RHS, you deal with 3 types intead of 2:
// variable-types for LHS and real & variable-types for RHS
Y y1 = (Y) x1; // real-type-LHS Y, variable type RHS X, real type RHS X
Y y1 = (Y) x2; // real-type-LHS Y, variable type RHS X, real type RHS Y

Open in new window


Basic rule is: Any assignment (x = y) works as long as there is a valid conversion available from the real type RHS to the variable type LHS.
Next question is clearly how do you define valid conversion? That's quite simple: Conversion from a derived type to super type is valid, the other way round is not.

Bit more jargon:
implicit casting: When you leave it to compiler (line number 3 & 4 above) to perform casting.
explicit casting: When you tell compiler (line number 7 & 8 above) to perform casting.
upcasting: In an assignment when the variable type is a base/super class of the real type. This can be explicit or implicit.
downcasting: In an assignment when the variable type is a derived/specialized class of the variable type on LHS. Note that I say "variable type on LHS" instead of real type, this is because although it's possible to write such an assignment, it will never work due to our Basic rule. This has to be explicit.

Another way of looking at this is using English:
casting from B to A works as long as A "is a" B. (where "is a" means inheritance or derivation, in this case A extends/implements B).

PS: Don't worry about being unable to run the example, it's not expected to run correctly.
0
gudii9Author Commented:
>>>
// of course if you have a variable on RHS, you deal with 3 types intead of 2:
// variable-types for LHS and real & variable-types for RHS
Y y1 = (Y) x1; // real-type-LHS Y, variable type RHS X, real type RHS X

you mean

Y y1 = (Y) x1; // real-type-LHS Y, variable type RHS X, real type RHS Y

right. instead of X it should be Y at end right. please advise

0
gudii9Author Commented:
still not clear on

>> Y y1 = (Y) x; // compiles ok but produces runtime error
     Z z1 = (Z) x; // compiles ok but produces runtime error
Object o1 = (Y) o; // compiles ok but produces runtime error
why it compiles but runtime error.
please advise

0
Exploring ASP.NET Core: Fundamentals

Learn to build web apps and services, IoT apps, and mobile backends by covering the fundamentals of ASP.NET Core and  exploring the core foundations for app libraries.

gudii9Author Commented:
I thought these two should compile, run fine as per the explanation i thought as given below

>>> //Y y3 = (Y) z;     inconvertible types (siblings)
(real-type-LHS Y, variable type RHS  Z, real type RHS Y)
//Z z3 = (Z) y;     inconvertible types (siblings)
(real-type-LHS Y, variable type RHS Y, real type RHS Z)

please advise
0
theKashyapCommented:
Y y1 = (Y) x1; // real-type-LHS Y, variable type RHS X, real type RHS X
you mean
Y y1 = (Y) x1; // real-type-LHS Y, variable type RHS X, real type RHS Y
right. instead of X it should be Y at end right. please advise
No. In my example x1 is defined on line number 3 (X x1 = new X()). So the real type of x1 is X.
Y y1 = (Y) x; // compiles ok but produces runtime error
Z z1 = (Z) x; // compiles ok but produces runtime error
In both these cases you're "down-casting". It's explicit casting, i.e. you've specified (Y) and (Z) on RHS.
By doing explicit cast you're telling compiler that "hey, don't bug me with compiler errors, I know that this is CORRECT, i.e. x is really pointing to an object of type Y.". And of course compiler trusts you. But at runtime it turns out that x is pointing to an object whose real type if X not Y. And the conversion is not valid, so you get ClassCast.. error.
Please note that you can NEVER change the real type of an object no matter how many times you keep casting it. real-type = object_instance.getClass().getName(). Hope you understood, this is very important. (see the example at bottom as well).
Object o1 = (Y) o; // compiles ok but produces runtime error
This is just trying to confuse. :-)
There are 2 casts involved here, one explicit "(Y) o" and another implicit "Object o1 = ...".
In the first one you're telling compiler cast o to Y. In the second one compiler itself performs a cast to "Object" as the variable-type on LHS (after the explicit cast, this is the confusing part) is Object and the RHS is Y.
Given that both the casts are valid, compilation goes thru. It doesn't run because the cast of o to Y fails (because it's not a valid conversion)
I thought these two should compile, run fine as per the explanation i thought as given below
>>> //Y y3 = (Y) z;     inconvertible types (siblings)
(real-type-LHS Y, variable type RHS  Z, real type RHS Y)
//Z z3 = (Z) y;     inconvertible types (siblings)
(real-type-LHS Y, variable type RHS Y, real type RHS Z)
Same as the first one. Perhaps to make it clearer see the example below:
      
        // This is the only real object created.
	Y y = new Y();

	// rest are all type casts. They DO NOT change
	// the real-type of the object
	X x2 = y;
	Y y1 = y;
	Y y2 = (Y) x2;
	Object o1 = y;
	Object o2 = x2;

	System.out.println(" y .getClass().getName() = " + y.getClass().getName());
	System.out.println(" x2.getClass().getName() = " + x2.getClass().getName());
	System.out.println(" y1.getClass().getName() = " + y1.getClass().getName());
	System.out.println(" y2.getClass().getName() = " + y2.getClass().getName());
	System.out.println(" o1.getClass().getName() = " + o1.getClass().getName());
	System.out.println(" o2.getClass().getName() = " + o2.getClass().getName());

	// Output is:
	// y .getClass().getName() = Y
	// x2.getClass().getName() = Y
	// y1.getClass().getName() = Y
	// y2.getClass().getName() = Y
	// o1.getClass().getName() = Y
	// o2.getClass().getName() = Y

Open in new window


HTH
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
gudii9Author Commented:
>>
      X x2 = y;
          
                Y y2 = (Y) x2;


Above two lines are not compiling. please advise



>>>


       Y y1 = (Y) x; // compiles ok but produces runtime error
            Z z1 = (Z) x; // compiles ok but produces runtime error

what is difference between above two lines from below two lines. why above two runtime error where as below runs fine

            Y y2 = (Y) x1; // compiles and runs ok (x1 is type Y)
            Z z2 = (Z) x2; // compiles and runs ok (x2 is type Z)

>>> Object o1 = (Y) o; // compiles ok but produces runtime error

also why above line produces runtime error.

i could not think them in terms of up or down casting. please advise. I understand now when you do down casting if you do not cast you get compile time error but when do we get run time error. that part still not clear. please advise
0
theKashyapCommented:
>>
      X x2 = y;
      Y y2 = (Y) x2;
Above two lines are not compiling. please advise
If you copy paste from my example in previous post they would compile. Won't work if you've changed the declaration of "y" somehow.


           Y y1 = (Y) x; // compiles ok but produces runtime error
            Z z1 = (Z) x; // compiles ok but produces runtime error

what is difference between above two lines from below two lines. why above two runtime error where as below runs fine
            Y y2 = (Y) x1; // compiles and runs ok (x1 is type Y)
            Z z2 = (Z) x2; // compiles and runs ok (x2 is type Z)
Here you are quite clearly confused between the "real" type and the variable type. Real type of "x" is "X" whereas real type of "x1" is "Y" that's why first one fails and second one works.
Again the real type of a variable can be found using "variable.getClass().getName()". So x.getClass().getName() is "X" where as x1.getClass().getName() is "Y".
Same goes the other line.


>>> Object o1 = (Y) o; // compiles ok but produces runtime error

also why above line produces runtime error.

i could not think them in terms of up or down casting. please advise. I understand now when you do down casting if you do not cast you get compile time error but when do we get run time error. that part still not clear. please advise
This line is just to confuse you. Although it looks like there is only casting, there are actually two casts happening.
First is the explicit where "o" is casted to type (Y). Second is implicit where the output of first cast (which is of type Y) is casted to type Object.
First cast (o casted to "Y") fails as o is not of type Y.

You get a runtime error when the casting is invalid. To quote "Conversion from a derived type to super type is valid, the other way round is not." see my first post.
0
gudii9Author Commented:
>>No. In my example x1 is defined on line number 3 (X x1 = new X()). So the real type of x1 is X.
Y y1 = (Y) x; // compiles ok but produces runtime error
Z z1 = (Z) x; // compiles ok but produces runtime error

In both these cases you're "down-casting". It's explicit casting, i.e. you've specified (Y) and (Z) on RHS.
By doing explicit cast you're telling compiler that "hey, don't bug me with compiler errors, I know that this is CORRECT, i.e. x is really pointing to an object of type Y.". And of course compiler trusts you. But at runtime it turns out that x is pointing to an object whose real type if X not Y. And the conversion is not valid, so you get ClassCast.. error.






why we need to explicitly down cast and tell compiler to ignore. We any way know it goind to throguh classcast error at later stage ie runtime. What is practical significance, advantage, uses of doing it like this. please advise
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Java

From novice to tech pro — start learning today.