Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Westi on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

casting problem

Status
Not open for further replies.

satellite03

IS-IT--Management
Dec 26, 2003
248
IN
Code:
class Base {}
class Sub extends Base {}
class Sub2 extends Base {}
public class CEx{
public static void main(String argv[])
{       Base b=new Base();
        Sub s=(Sub) b;
}

}

javac CEx.java // compiled ok


java CEx // runtime exception

Exception in thread "main" java.lang.ClassCastException
at CEx.main(CEx.java:8)


why this error ?


The casting Sub s=(Sub) b; , i think it is a perfectly legal thing.

bcoz it has parent child relationship in the inheritance heirarchy. so, this can not be illegal . then why it is giving "ClassCastException" . one more interesting thing is , compilation has given it a cleanchit but probelm is coming at the runtime !!

i want to know why there is error ?











 
It gives the error because "b" is a "Base" It is not a "Sub" or "Sub2"

If you wrote
Code:
Base b=new Sub();
Sub s=(Sub) b;
It wouldn't give an error. (Although I can't test it for the moment)
 
but why that is wrong ? if that is wrong then why the compiler remained silent at the compilation time and at the runtime exception came ?
i am interested to know the cause of error.


as i found that casting down in the heirarchy require explicit casting ( thats what has been done here ).

and casting up is implicit.
so, why the error is coming?

 
At compile time the compiler only knows that "b is a Base" and "s is a Sub" . The compiler does not know what you are going to put in "b" at runtime before executing the cast.
At runtime "b" could contain a "Base" a "Sub" or a "Sub2"
Code:
 Base b = null; 
 if (...)
   b = new Base(); // Cast will give runtime error
 else
   if (...)
     b = new Sub(); // Cast without runtime error
   else
     b = new Sub2(); // Cast will give runtime error

 Sub s = (Sub) b;
Do you know what will be in "b" at runtime ? Neither does the compiler. So he doesn't complain. At runtime you will get an error if b contains a Base or Sub2, not if it contains a Sub. That's why it is recommended to do an "instanceof" before the cast
Code:
if (b instanceof Sub) {
  Sub s = (Sub)b;
  ...
}
 
hologram:
I agree in general, but not in detail.
Of course we know (in the original code) what 'b' is. 'b' is a Base. The compiler doesn't know, but a compiler could know, I think.

satelite03:
If you take a more expressive example:
class Animal, class Gnu extends Animal, class Yacc, extends Animal.

Since every Gnu is an animal, and every Yacc, you may cast them to plain Animals.
But if you have an Animal, how do you make a Gnu of it?
If your Gnu has a horn, but Animal of course does't (it might be a fish, a bird, ...) where do you get it from?

It doesn't depend on the fact, whether your Gnu really has a horn.
Think about an empty animal class, and Gnu has 'String name' and 'int age'.
Think about an class Harddrive, containing a 'String manufactor, int capacity'.
Hey - shouldn't it be easy to cast a Gnu to a Harddrive?
Of course not - it depends on the inheritance logic, not on the inner implementation.

As hologram pointed out, you may cast an animal to a gnu, if this animal 'is a gnu', or 'was a gnu in original' or a class derived from gnu, i.e. 'NorthAmericanGnu extends Gnu'.

I can imagine a compiler which tries to find out, but will still not ensure a cast to match.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top