aspose file tools*
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes reference assignment and casting question Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "reference assignment and casting question" Watch "reference assignment and casting question" New topic
Author

reference assignment and casting question

Bernd Stransky
Ranch Hand

Joined: Nov 20, 2001
Posts: 47
Hi,
I found the following question/answer on the web.
Can someone explain to me why b is the correct answer and the others are not?
I know about the rules of reference assignment and downcasting, but this is a bit confusing for me.
Class definition:
class ApBase extends Object implements Runnable {}
class ApDerived extends ApBase implements Observer {}
----------------------------
Sample code:
ApBase aBase = new ApBase();
ApDerived aDer = new ApDerived();
-----------------------------------
Which assignments are correct:
a) Object obj = aBase;
Runnable rn = obj;
b) Object obj = aBase;
Runnable rn = (Runnable) obj;
c) Object obj = aBase;
Observer ob = (Observer) aBase;
d) Object obj = aDer;
Observer ob2 = obj;
The answer was b.
Thanks,
Bernd
Valentin Crettaz
Gold Digger
Sheriff

Joined: Aug 26, 2001
Posts: 7610
Are you ok with the fact that this is a compile-time issue? Whenever you explicitely provide a cast, the compiler will not complain, however, you might just get into trouble at runtime. Explicitely casting is telling the compiler that you know what you are doing. It doesn't mean that you do the thing correctly, though, in which case you'll get a ClassCastException at runtime.
In the option b, obj references an object of class ApBase which implements Runnable. When you assign obj to m you have to provide an explicit cast which tells the compiler that obj does actually reference an instance of a class that implements Runnable. If you don't provide that cast, then the compiler can figure out that the class Object itself does not implement Runnable and won't allow you to go further. In this respect, options a and d have the same problem since class Object neither implements Runnable nor Observer and the compiler knows that.
In option c, you certify the compiler that class ApBase implements Observer which is wrong. But it won't complain since it has no way to know that this is not true. The interpreter, however, will not allow that and throw a ClassCastException at runtime.
To make this even more clear, you have to distinguish between compile-time type and runtime type.
In the declaration
Object obj = aBase;
obj has the compile-time type Object and the runtime type ApBase. The compiler always bases itself on the compile-time type or declared type.
It cannot make assumptions about the runtime type since runtime usually happens after compile-time.
I'm not sure if this answers your question... Let us know if you need more explanations...
[ February 15, 2002: Message edited by: Valentin Crettaz ]

SCJP 5, SCJD, SCBCD, SCWCD, SCDJWS, IBM XML
[Blog] [Blogroll] [My Reviews] My Linked In
Richard Lakin
Greenhorn

Joined: Jan 22, 2002
Posts: 7
ok, this in my understanding.
a) 2nd line is wrong because you're trying to convert 'obj' (reference type 'Object') to 'rn' (interface 'Runnable'). The rule says that to convert a class to an interface type, the class must implement the interface. It doesn't in this case - 'Object' does not implement 'Runnable'.
b) is fine because the compiler will always accept the CAST of a Non-Final class to an interface.
c) 2nd line will compile (see rule above) but it won't run as the class of aBase (ApBase) is incompatible with interface 'Observer'
d) 2nd line wrong because, for conversion, 'obj' (Reference type 'Object') must implement the interface it's being converted to, ie, 'Observer', and this is not the case. In this case if a cast was employed (Observer ob2 = (ApDerived)obj) it would work as the class of obj is ApDerived, and that class does implement Observer.
Well this is my opinion.
I recommend the Java2 Certification Study guide which goes through all this well. I'm only just getting to grips with it too, but and someone correct me if I'm wrong please, the following helps me:
Where ApBase aBase = new ApDerived()
the reference type of aBase is ApBase.
the class type of aBase is ApDerived.
The compiler checks only the reference type, the class is determined at Runtime.
PS: the question is from Bill Brogden's book I believe if you want to check further.
Bernd Stransky
Ranch Hand

Joined: Nov 20, 2001
Posts: 47
Originally posted by Valentin Crettaz:
Are you ok with the fact that this is a compile-time issue? Whenever you explicitely provide a cast, the compiler will not complain, however, you might just get into trouble at runtime. Explicitely casting is telling the compiler that you know what you are doing. It doesn't mean that you do the thing correctly, though, in which case you'll get a ClassCastException at runtime.
In the option b, obj references an object of class ApBase which implements Runnable. When you assign obj to m you have to provide an explicit cast which tells the compiler that obj does actually reference an instance of a class that implements Runnable. If you don't provide that cast, then the compiler can figure out that the class Object itself does not implement Runnable and won't allow you to go further. In this respect, options a and d have the same problem since class Object neither implements Runnable nor Observer and the compiler knows that.
In option c, you certify the compiler that class ApBase implements Observer which is wrong. But it won't complain since it has no way to know that this is not true. The interpreter, however, will not allow that and throw a ClassCastException at runtime.
To make this even more clear, you have to distinguish between compile-time type and runtime type.
In the declaration
Object obj = aBase;
obj has the compile-time type Object and the runtime type ApBase. The compiler always bases itself on the compile-time type or declared type.
It cannot make assumptions about the runtime type since runtime usually happens after compile-time.
I'm not sure if this answers your question... Let us know if you need more explanations...
[ February 15, 2002: Message edited by: Valentin Crettaz ]

Hi Valentin,
excellent and easy to understand explanations - this helps me a lot, thank you.
-Bernd
Jose Botella
Ranch Hand

Joined: Jul 03, 2001
Posts: 2120
Whenever you explicitely provide a cast, the compiler will not complain,
There will be an error at compile time in a cast if:
The types are son-son, instead of father-son or son-father.
A final class is casted to an interface that it doesn't implement, or viceversa.
A primitive array type is casted to a different array type.
An interface is casted to another non-related interface which declares methods with the same signature, but different return type.
A boolean is casted to ... bla bla bla ...
I know you knew them Val, but others maybe not
[ February 15, 2002: Message edited by: Jose Botella ]

SCJP2. Please Indent your code using UBB Code
Valentin Crettaz
Gold Digger
Sheriff

Joined: Aug 26, 2001
Posts: 7610
You are right Jose, I should have mentioned all that, it is very important, indeed. *slap on fingers*
Erik Dark
Ranch Hand

Joined: Jan 28, 2002
Posts: 107
The question is from Bill Brogden's "38 hardest questions" and for purposes of completeness I'll quote the answers he gives.
Answer a fails to compile. As far as the compiler is
concerned, obj is a plain Object so it objects to the
assignment to a Runnable reference.
Answer b compiles and runs. The compiler assumes you
know what you are doing with the cast to Runnable.
Answer c compiles but fails to run. Because of the
specific cast, the compiler thinks you know what you are
doing, but the type of the aBase reference is checked
when the statement executes and a ClassCastException is
thrown.
Answer d fails to compile. As far as the compiler is
concerned, obj is a plain Object so it objects to the
assignment to an Observer reference.

Erik Dark
Bernd Stransky
Ranch Hand

Joined: Nov 20, 2001
Posts: 47
Originally posted by Erik Dark:
The question is from Bill Brogden's "38 hardest questions" and for purposes of completeness I'll quote the answers he gives.

Erik Dark

I didn't even know that these were the "hardest questions" - no wonder I wasn't doing so well (70%;-), but I guess that was a good thing.
Where did you get the answers from?
-Bernd
Erik Dark
Ranch Hand

Joined: Jan 28, 2002
Posts: 107
Hi Bernd,
You can find the questions here. After you've finished the mock you can review the answers and by clicking on each also the wrong ones..
Erik Dark
Jose Botella
Ranch Hand

Joined: Jul 03, 2001
Posts: 2120
This is easy and helpul to remember.
instanceof and == fails at compile time in similar situations where a cast does
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
 
subject: reference assignment and casting question