• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Another examLab casting question

 
Ranch Hand
Posts: 129
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


which of the following statements inserted will compile and run without errors or exceptions?
a- b=(B)a;
b- d = (D)b;
c- d= (D)(B)a;
d-c=(C)d;
e-b = (B)d;


Answer C is wrong ,because it gives a runtime exception (ClassCastException).The variable 'a' already contains an instance of B. An instance of B ,cannot be referred by a D reference .because B is not a D .(D is a B)

Help I don't understand the answer ,I thought it was like making a downcast two times for variable a. And what does he mean b is not a d? I mean a downcast is legal ,right?
 
Ranch Hand
Posts: 124
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Although I have never seen a double cast like that before, I assumed it was just as
it appeared, and after running some code I think it is:



So assuming the cast to Fodo works (B in your question), the cast to
Wacko works at compile time since Wacko (D) inherits from Fodo (B).
But at runtime, the jvm notices that the object that was in b was actually
a Fodo object (B), and that cannot be turned into a subclass object at
runtime, a Wacko (D), So the jvm throws the ClassCastException.
Remember, the question specified that the options must both compile
*and* run.

Perhaps the explanation in ExamLab was slightly vague.
 
S Ali
Ranch Hand
Posts: 129
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


I also did some examples and sorta got it .So I guess JVM never allows downcasts or what?
 
Ranch Hand
Posts: 814
Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi, S Ali

The casting related problem many times discussed in the SCJP forum.
Do a search on this topic you will get lot of information about casting.
You can see this thread
 
Ken Truitt
Ranch Hand
Posts: 124
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

I guess the jvm never allows downcasts



What about this:



When you have a cast on the right side of an assignment operator, you are

1)asking the compiler to understand the reference on the right side of the assignment
operator to be the (cast) type:
The compiler will allow the cast if the (cast) type is in the same inheritance
tree as the reference on the left side of the assignment operator.

2)asking the compiler to assign the (cast) type to the reference on the left side of the
assignment operator:
The compiler will allow the assignment (in light of the cast) if the reference on the left
of the assignment operator is the same as or a superclass of the reference type on the
right side of the assignment operator, after the cast.

3)asking the jvm to allow the reference on the right side of the assignment operator
to change to the (cast) type and still refer to the actual object it points to:
The jvm will allow the cast if the (cast) type (the target type) is the same as or
a superclass of the actual object type (ie cast (Animal) to (Dog) if actual object is Dog)


So there's two issues on the right side of the assignment operator, and one on the left.
 
Ninad Kulkarni
Ranch Hand
Posts: 814
Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi, Ken


I hope this clears
Correct me if I am wrong
 
Ken Truitt
Ranch Hand
Posts: 124
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Yes I think that is correct.



Actually at compile time I think it's more like the explicit cast tells the compiler that instead of an Animal reference
which points to some object being assigned, it wants to change the reference, which points to some object that will be
assigned, to be of type Dog now rathern than Animal. The compiler allows the cast because Dog, the proposed
reference type, is in the same inheritance tree as Animal, and the compiler allows the assignment because the
reference type on the left of the assignment operator ('='), is a supertype of Dog.

Then, as you say, the jvm examines the actual object pointed to by the referene on the right of the '=' operator and sees
that its type is neither the same nor a superclass of Dog, so it throws a ClassCastException.

My point here is that the explicit cast doesn't 'tell the compiler that a is really referring to a Dog[sic] object', it just tells the
compiler that it wants 'a' to be a Dog reference rather than an Animal reference, and is that all right. ...and then after
the compiler allows both the cast and the assignment, the jvm disallows the cast due to the incompatibility of the actual
object type and the proposed reference type.
 
Ninad Kulkarni
Ranch Hand
Posts: 814
Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

compiler that it wants 'a' to be a Dog reference rather than an Animal reference, and is that all right. ...and then after
the compiler allows both the cast and the assignment



Yes Ken you are perfectly correct.
If you are confused by my previous statement I will explain it again.
I want to tell the that "a is really refering to dog object by using explicit down cast" so compiler allow it.
After down cast compiler see reference variable a as a dog type referencence not animal type reference. My meaning is we do manual explicit cast in such a way that we say a is really refering to dog object.
that is why upcast happens automatically and down cast happens manually.

Thanks Ken for your reply

I hope this clears
Correct me if I am wrong
 
Ranch Hand
Posts: 537
Eclipse IDE Python Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I guess the is-a test is forgotten. The implicit upcast happens only if its is-a test is passed well more or less.
 
Ken Truitt
Ranch Hand
Posts: 124
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Whups here's a correction to my earlier post:

When you have a cast on the right side of an assignment operator, you are

1)asking the compiler to understand the reference on the right side of the assignment
operator to be the (cast) type:
The compiler will allow the cast if the (cast) type is in the same inheritance
tree as the reference [on the left side of the assignment operator.<--WRONG]
being cast. If it's not, the compiler reports an inconvertible types error

2)asking the compiler to assign the (cast) type to the reference on the left side of the
assignment operator:
The compiler will allow the assignment (in light of the cast) if the reference on the left
of the assignment operator is the same as or a superclass of the reference type on the
right side of the assignment operator, after the cast. [new -->] If it's not, the compiler
reports an incompatible types error

3)asking the jvm to allow the reference on the right side of the assignment operator
to change to the (cast) type and still refer to the actual object it points to:
The jvm will allow the cast if the (cast) type (the target type) is the same as or
a superclass of the actual object type (ie cast (Animal) to (Dog) if actual object is Dog)
[new-->] If it's not, the JVM throws a ClassCastException.

--------------------------------

Ninad, I disagree that the explicit downcast tells the compiler anything about the atual object pointed to by the reference being cast.
The explicit cast *asks* the compiler to simply change the reference *type* on the right side of the assignment operator. The
compiler decides whether to allow this based on whether the (target) type is in the same inheritance tree as the original reference type
(on the right side). So

Animal a = new Animal();
Dog d = new Dog();
Cat c = new Cat();

a = (Dog)c; // Dog is NOT in the same inheritance tree as c's reference type, Cat, so COMPILER reports an "inconvertible type" error

a = new Dog(); // we now assign a Dog object to the Animal reference

Animal a2 = (Dog)a; // Dog is in the same inheritance tree as a's reference type Animal, so the compiler allows the cast;
//the compiler has allowed the cast now it checks the assignment--and it will NOT allow you to assign a Dog reference
//to an Animal reference (it still knows nothing of the actual object type in a) so it reports an "incompatible type" error

Animal a3 = (Cat)a; // the compiler allows this cast because Cat is in the same inheritance tree as a's reference type, Animal
//the compiler allows the ASSIGNMENT because an Animal reference can be assigned a Cat reference
//but the problem here is that at runtime, the JVM checks the type of the actual object in a (which we made a Dog above)
//and it discovers that it's a Dog, which is not a Cat or a supertype of Cat, so the jvm throws a ClassCastException.

This says nothing about casting references that don't point to objects (null references) which can be cast to anything, and
it doesn't say anything about interface types.


 
Ninad Kulkarni
Ranch Hand
Posts: 814
Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ken, Thanks for notification for misinterpretation of *tell* word.
The *tell* word makes more confusion in explaination so I withdraw *tell* word from my previous statements regarding casting. I used *tell* word for our convenience only to understand what happens with code while compiling and running. Actually *tell* word does not tell anything to the compiler. Compiler sees at type only.

The following is a quote from my previous statements.

After down cast compiler see reference variable a as a dog type referencence not animal type reference. My meaning is we do manual explicit cast in such a way that we say a is really refering to dog object.
that is why upcast happens automatically and down cast happens manually.



Down cast happens mannually with same inheritance not with sibling objects like Dog and Cat.
If you want to do following




Ken, Below is a quote from your statement

Animal a2 = (Dog)a; // Dog is in the same inheritance tree as a's reference type Animal, so the compiler allows the cast;
//the compiler has allowed the cast now it checks the assignment--and it will NOT allow you to assign a Dog reference
//to an Animal reference (it still knows nothing of the actual object type in a) so it reports an "incompatible type" error





See the given below code



I hope this clears
 
Ken Truitt
Ranch Hand
Posts: 124
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I have been very pedantic here because I think the subject is rather confusing. I think if you look at my (revised)
3-step analysis, though, it details *all* of the factors to consider in evaluating reference casts. When I can I like
to understand every detail explicitly. I'm sure you have it so it's all good.
 
Ranch Hand
Posts: 32
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

class AA {}

class BB extends AA {}

class CC extends AA{}

public class CastingQ extends BB
{

public static void main(String[] args)
{
AA a=new BB();

BB b=new CastingQ();

CC c=new CC();

CastingQ d= null;


//the casting code here

b = (BB)a;

// d = (CastingQ)b;

// d = (CastingQ)(BB)a;

b = (BB)d;



}


}

Here I am getting a ClassCast Exception on the commented lines . I am not getting it as
1.CastingQ extends BB
2. b points to CastingQ
3. I have done a explicit downcast of b to CastingQ

Still why is it giving the exception?

Please help.
 
Ken Truitt
Ranch Hand
Posts: 124
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I explained the rules that govern this situation, as I understand them, as best as I could above.
So in this question I would look at the two compiler issues first:
1)is the (cast) type in the same inheritance tree as the reference to be cast?
2)assuming the cast is allowed by the compiler, is the resulting assignment of
the (cast) type to the reference on the left side of the '=' operator legal?


[line numbers added by me]

In line 1, a is in the same inheritance tree as BB (it's AA--the superclass) so compiler test 1 is passed.
Then for the second compiler question, is the assignment legal if the cast is allowed--a BB reference can
always be assigned to a BB reference, so that's good. Finally, the 3rd question to evaluate has to do with
the runtime issue of the actual type of the object in the reference being cast. It's actually a BB, and the cast
will succeed if the (cast) type is the same type or a superclass of the actual type (if the cast type IS-A
[reference type]). BB IS-A BB, so this statement checks out with all three tests--it compiles and it runs.

In line 2, test 1 is passed because CastingQ is in the same inheritance tree as AA; test 2 is passed because,
assuming the cast is allowed, a CastingQ can be assigned to a reference of the same type, CastingQ(d).
So this statement compiles, but does it run? Does it pass test 3?--is the actual object in b, a BB (it started with
a CastingQ, but it was assigned a BB in line # 1 above), the same or a superclass of the (cast) type--CastingQ?
No, it's a superclass of CastingQ. So a failure in test 3 leads to a ClassCastException, as stated in my previous post.

The analysis for line # 3 above is exactly the same except that before attempting to cast the a reference to CastingQ,
it is successfully cast to BB.
 
Abhik Ghosh
Ranch Hand
Posts: 32
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Yes Ken, I get it now.... the thing that I was missing is that the lines


if put exlusively are coorect in each case,as they follow all the 3 steps of casting. However if they are both put, then in line 1
b refers to BB,a nd so cannot be casted to CastingQ.
As for line

a can be downcasted to BB and not to CastingQ,so there is the ClassCastException
 
Don't get me started about those stupid light bulbs.
reply
    Bookmark Topic Watch Topic
  • New Topic