wood burning stoves 2.0*
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes Narrowing reference Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login

Win a copy of Android Security Essentials Live Lessons this week in the Android forum!
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "Narrowing reference" Watch "Narrowing reference" New topic

Narrowing reference

Eugene Lea

Joined: Sep 30, 2002
Posts: 12
In JSL written:
topic 5.1.5
The following conversions are called the narrowing reference conversions:
From any class type S to any class type T, provided that S is a superclass of T.
Then, why following code occur run-time error ?
interface I1 {}
interface I2 {}
class Base implements I1 {}
class Sub extends Base implements I2 {}
public class test31 {
public static void main(String[] args) {
Base base = new Base();
Sub sub = (Sub)base; //ClassCastException why??
jay denzel
Ranch Hand

Joined: Sep 18, 2002
Posts: 57
Because at runtime base denotes a Base Object and therefore can not be cast to a Sub Object. If you change Base base = new Base(); to Base base = new Sub(); both there will be no ClassCastException.
Hope this helps.
Eugene Lea

Joined: Sep 30, 2002
Posts: 12
Thank you for your help.
I`m understood.
Tom Calverley

Joined: Sep 30, 2002
Posts: 1
The question you posted is simplified by ignoring the interfaces (although the reason for the ClassCastException remains the same).
1 class Base {}
3 class Sub extends Base{}
5 public class A {
6 public static void main(String[] args) {
7 Base base = new Base();
8 Sub sub = (Sub)base; //ClassCastException 9 }
10 }
For this code to compile successfully (as it does) you had to cast the 'base' object reference to the type 'Sub'. Removing this cast results in a compilation error to inform you that the object references have incompatible types.
This is because when converting object reference types in an assignment statement, if both the old type and the new type are instances of some class, the old type must be a subclass of the new type.
However, since you have included the cast to 'Sub', your code compiles successfully.
A further check made at compile time is to ensure that when casting from one type to another, where both types are instances of some class, that one must be a subclass of the other. As we already know for this example compilation succeeds, since Base is a superclass of Sub.
The exception that occurs at runtime is due to the follow rule: The class of the expression being converted must be the same as, or must inherit from, the object reference type you are converting to.
In your example the class of the expression being converted is 'Base' which is neither the same as, nor does it inherit from, the 'sub' object reference type.
The reason that the compiler cannot spot the error is because it cannot determine the type of the object referred to by the 'base' object reference. You could, for example, create an object reference 'base' of type 'Base' that holds reference to an object of type 'Sub'.
Amending line 5 in the code above to 'Base base = new Sub();' illustrates this point and results in no compilation errors and no runtime exceptions.
Consider Paul's rocket mass heater.
subject: Narrowing reference
Similar Threads
assignment question doubt ??
Dan's Reference Conversion Doubt
Regarding object casting
Reference type casting doubt?