This week's giveaways are in the MongoDB and Jobs Discussion forums. We're giving away four copies of Mongo DB Applied Patterns and 4 resume reviews from Five Year Itch and have the authors/reps on-line! See this thread and this one for details.
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
posted
0
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
posted
0
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
posted
0
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).]
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
posted
0
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
posted
0
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
posted
0
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
posted
0
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
posted
0
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