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


Win a copy of Murach's Java Servlets and JSP this week in the Servlets forum!
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "Class cast exception" Watch "Class cast exception" New topic
Author

Class cast exception

SHALINI PATEL
Ranch Hand

Joined: Oct 31, 2000
Posts: 41
I am not able to get this piece of code......
It compiles fine, but gives a ClassCastException during runtime.
I am really not able to understand class cast exception.
Thanks in advance

lakshmi nair
Ranch Hand

Joined: Oct 11, 2000
Posts: 63
Exception is thrown at the following line.
b= (B[])a1;
Here a1 which contains an A[10] array is being cast to a B[] which is of type subclass of A and hence cannot be casted. Thats why the exception.
Lakshmi
sarim raza
Ranch Hand

Joined: Nov 02, 2000
Posts: 232
Dear Shalini
i dont see any problems with this, since one array is the subclass of another it should be castable.
are you satisfied with the answer lakshmi gave you?
Jane Griscti
Ranch Hand

Joined: Aug 30, 2000
Posts: 3141
Hi Shalini,
You can cast up the heirarchy but not down. ie you can cast an 'A' object to 'B' as, thru inheritance, subclass 'B' will contain everything available in 'A'; however, you can't cast an 'A' object to 'B' as 'A' does not contain all the data and methods that class 'B' contains.
Casts will often compile without error as the compiler assumes you know what you are doing; and the cast object will really be the same type as the cast type; however, at runtime, the actual type of the object is checked and if it violates the 'cast' rules, the cast will fail.
Hope that helps.
------------------
Jane
The cure for boredom is curiosity.
There is no cure for curiousity.
-- Dorothy Parker
[This message has been edited by Jane Griscti (edited November 03, 2000).]


Jane Griscti
SCJP, Co-author Mike Meyers' Java 2 Certification Passport
lakshmi nair
Ranch Hand

Joined: Oct 11, 2000
Posts: 63
I think this is what Jane meant to say ...
You can cast up the heirarchy but not down. ie you can cast an 'B' object to 'A' as, thru inheritance, subclass 'B' will contain everything available in 'A'; however, you can't cast an 'A' object to 'B' as 'A' does not contain all the data and methods that class 'B' contains.
Thanx
Lakshmi

Hi Shalini,
You can cast up the heirarchy but not down. ie you can cast an 'A' object to 'B' as, thru inheritance, subclass 'B' will contain everything available in 'A'; however, you can't cast an 'A' object to 'B' as 'A' does not contain all the data and methods that class 'B' contains.
Casts will often compile without error as the compiler assumes you know what you are doing; and the cast object will really be the same type as the cast type; however, at runtime, the actual type of the object is checked and if it violates the 'cast' rules, the cast will fail.
Hope that helps.
------------------
Jane
The cure for boredom is curiosity.
There is no cure for curiousity.
-- Dorothy Parker
[This message has been edited by Jane Griscti (edited November 03, 2000).]

Travis Gibson
Ranch Hand

Joined: Oct 17, 2000
Posts: 100
Why wouldn't the runtime error error on
b = (B[])a;
I mean afterall the object "a" also represent the SuperClass which is being casted to subclass object "b".
Originally posted by lakshmi nair:
Exception is thrown at the following line.
b= (B[])a1;
Here a1 which contains an A[10] array is being cast to a B[] which is of type subclass of A and hence cannot be casted. Thats why the exception.
Lakshmi


Regards,<BR>Travis M. Gibson, SCJP<BR>Java Developer<BR>www.travismgibson.com<BR>travis@travismgibson.com
yogesh sood
Ranch Hand

Joined: Aug 31, 2000
Posts: 108
class A{}
class B extends A{}
lets have look at clause in JLS
"A variable of array type holds a reference to an object. Declaring a variable of array type does not create an array object or allocate any space for array components. It creates only the variable itself, which can contain a reference to an array."

int sr[];//no memeory
int sr=new int[]//object created

if u write
A arr[]={new ??,new??};
irrespective of type of member the array object will be type A[]
i.e if u write
A arr[]={new B(),new B()};
or
A arr[]={new B(),new A()};
ur array object is type of A[]
now whwn ever u try to cast it to subclass

B ar[]=(B[])arr;
there will be no error at compile time coz what compiler want is that classes of array should be in class hiearchy.
at runtime there will be exception thrown coz array type of arr is A[] and u r casting to B[].it must be B[] or its subclass
Now if u write
B ar[]=new B[3];
A arr[]=(A[])ar;

There will be no exception as array object is of B[] type and which is subclass of A so Object of sublcass is also Object of Super class;
now come the real point how to do it???
see
A arr[]=new B[2];
now object of array Type is B[].
but u cannot have now like
arr[0]=new A(); //line 3
There will be ArrayStoreException will be thrown.
coz array is now of type B[] and that cannot hold Superclass object.however it can always have object of
subclass.
i.e
arr[0]=new C();

Following Lines from JLS chapter 10 u can see effect in line 3
"An assignment to an element of an array whose type is T[], where T is a reference type, is checked at run-time to ensure that the value assigned can be assigned to the actual element type of the array, where the actual element type may be any reference type that is assignable to T. "
At compile time, an assignment to an element of A is checked to make sure that the value assigned is a A. But since arr holds a reference to an array of B, the assignment is valid only if the type of the value assigned at run-time is, more specifically, a B.
Now apply same rule on ur problem

A[] a,a1; //line 1 No memory
B[] b; //line 2 No memory
a = new A[10]; //Array object of type A[]
a1=a; //line 4Array Object of type A[] is assign to A[] a1
b = new B[20]; //Array object of type B[]
a=b; // line 6 B[] is assign to A[]
b= (B[])a; // line 7 B[] is assign to B[]
b= (B[])a1 //line 8 Exception thrown

Main line is line 6 in which B[] is assign to a which is supose to take array type of A[] since B[] is also
A[] this is valid
But Now a have array type B[]
and if u try to write this a[0]=new A();
u will get ArrayStoreException coz object of a is B[] type it can only hold references to object of class B or its subclasses
line 7 is valid due to line 6 if u commented line 6 u will get exception at line 7 due to line 6
a now has B[] object and u r casting it to B[] no Problem at all (Thats answer for Gibson question)
Now at line 8 u get exception coz runtime object of a1 is A[] and u r casting it to B[] thats why exception is thrown
if u place line 4 after line 6 u will not get error i hope by now u all know why.
Hope this will Help
don't forget to see http://www.javaranch.com/ubb/Forum24/HTML/005116.html

[This message has been edited by yogesh sood (edited November 03, 2000).]

If its green its biology if its stinkks its chemistry if it has numbers it is Maths and if it doesn't work its TECHNOLOGY
SHALINI PATEL
Ranch Hand

Joined: Oct 31, 2000
Posts: 41
HI GAUTAM,
OK I agree with u that
first= second is true,
because an object of the subclass can be assigned to an object of superclass, because the subclass has FEATURES OF SUPERCLASS+ ITS OWN FEATURES.. OK. Hence its like giving some more privilage to the superclass object by assigning it to the subclass object.
My question was something different...Why dont we get a run time error in the first case b=(B[])a and why we get a runtime error in second case........
I think so I got it now
SHALINI PATEL
Ranch Hand

Joined: Oct 31, 2000
Posts: 41
Thanks everybody for such a wonderful explaination
Yogesh, I just wanted to clear out what I have understood,

So I am just elaborating the lines 4 and 6.
So what I understand from this discussion is that during casting yu look to the class of the object newA[10] and newB[20] which is A and B respectively.
I think I got it... correct me if I am wrong somewhere...
Also one more thing, I am not able to get this logic, that why do we always want to assign a subclass object reference to a superclass
say Window w1= new Frame();
So now its like saying that my window will have features of the frame i.e it will have a title bar, an icon and menus....
What is the sense in doing it that way.. I could have said
Frame w1= new Frame(); and still I would have got all the features........... I hope yu understand what I mean..
Thanks,
shalini...
yogesh sood
Ranch Hand

Joined: Aug 31, 2000
Posts: 108
Yes u got it right we look at the object of array type when dealing with casting.

Now come to second point why we need Upcasting (mean subclass object to superclass varible)
correcting u r lines

Window w1= new Frame();
So now its like saying that my window will have features of the window custmized to Frame (By overriding methods) but not those which are added by Frame.
Frame w1= new Frame(); and still I would have got all the features inherited from Window as well added By Frame


Main point is that both expression is not same super class can't access features added by subclass mean if there is method which is define by Frame ,u can't access that method using Reference varible of Window.
However u can always do that by down casting.
lets see an example

consider following class hiearchy
abstract class Instrument{
abstract void Play(){}
}
class Guitar extends Instrument{
void Play(){
System.out.println("Playing Guitar");
}
}

class Drums extends Instrument{
void Play(){
System.out.println("Playing Drums");
}
}

class Violin extends Instrument{
void Play(){
System.out.println("Playing Violin");
}
}

public class Harmony{
Instrument I;
//this method not using Polymorphism
void Start( Instrument temp)
{
I=temp;
if (I instanceof Guitar)
(Guitar)I.play();
else if (I instanceof VIolin)
(Violin)I.play();
else
(Drums)I.play();
}
}
As u can see how clustered is above cousre without using Polymorphism and u may have no. of Instument as u go on increasing Instrument u have to increase no. of if blocks in OOP(Object Oriented Prog.) we tend to write code that can be extend easily without change in Interface.

now u know that subclass object can be assigned to super class i.e Upcasting and a method never forgot its class mean although u have object of subclass in super class overriden method of subclass will be called.
using in our example even if u use Instrument class to hold object of different subclasses call to Play
method will always be according to class of object being held by I.
so we can rewrite Start() Method as

void Start(Instrument temp)
{
I.play();
}

Better way to under stand is through practical example
Good example is thread class
Thread(runable target)
The default run may look like this
public void run(){
if (target!=null){target.run()}
}
Here target is runable object we passed to the Thread's constructor.
so if Upcasting &Polymorphism were not allowed u would not have been using simple way of creating Thread.
coz u can name ur class any thing and sir James Gosling ,Patric Naughtonand many more not know them
so they even can't write code using if else as we have written above.
Hope this will Help
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Class cast exception
 
Similar Threads
Polymorphism Problem using Covariant types
Class Cast related query
fwd or backward ,don't know which reference??
Problem with BeanUtils
TYPE CAST