Help coderanch get a
new server
by contributing to the fundraiser
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Ron McLeod
  • Paul Clapham
  • Devaka Cooray
  • Liutauras Vilda
Sheriffs:
  • Jeanne Boyarsky
  • paul wheaton
  • Henry Wong
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Tim Moores
  • Carey Brown
  • Mikalai Zaikin
Bartenders:
  • Lou Hamers
  • Piet Souris
  • Frits Walraven

short casting question

 
Ranch Hand
Posts: 38
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Base[] base = {new Base()};
Sub sub[] = new Sub[1];
Object obj = base;
sub = (Sub[])obj;

why error occurs in the last line? why can't I cast obj to Sub[] type?
THANKS!!
 
Serena Chen
Ranch Hand
Posts: 38
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
sorry forget to say one thing important.
the above question is assuming Sub[] extends Base[]
 
Ranch Hand
Posts: 2120
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Because the runtime type of obj is Base[] and Base cannot casted to Sub.

JLS 5.5 Casting Conversion applies
 
Serena Chen
Ranch Hand
Posts: 38
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
i still don't get it..so..since Sub[] already extends Base[], why can't it "explicitly" cast obj into Sub[]?
shouldn't this always be true:
//Subclass extends Superclass
Subclass A; Superclass B;
A = (Subclass)B;
please explain THANK YOU!!!
 
Greenhorn
Posts: 15
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I believe this is in the JLS Here.

If doing a cast of the R ordinary class to the T ordinary class type, ie: (T)R, then R must be either the same class as T or a subclass of T, or a run-time exception is thrown.


In your example, (Subclass)B, consider:

As Jose said, at runtime it makes no sense to try to refer to your object as a String. o (R) is not a subclass of String (T).
In other words, you can refer to an object using a more general reference in the class hierarchy but not a more specialized one.
Something like that
 
Serena Chen
Ranch Hand
Posts: 38
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks and i know that i can only cast object to a more generalized type but isn't that for explicit casting(like the question above),
(Sub[])obj, I can cast obj to a more restricted type give that it's an explicit cast?
i guess i am too confused...please let me know why this explicit cast doesn't work.
thanks!!!
 
mister krabs
Posts: 13974
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
obj is an array containing Base objects. It is not an array containing Sub objects. You are attempting to put an array of Base objects into an array of Sub objects. Since Sub objects can have methods that Base objects don't, this is not permitted. The cast tells the compiler that you know what you are doing and to allow it. But at runtime, this fails because a Base object can't be held in a Sub pointer.
Let's look at an example of the problem you are creating.
Imagine these two classes:

We end up trying to run the blow() method on an Instrument! This is obviously not going to work. The rule is, you can always go up the hierarchy without a cast and without a problem. You can go down the hierarchy with a cast but it will only work if the object is really the type you are casting it to. The JVM can only determine this at runtime.
 
Ranch Hand
Posts: 73
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Serena,
Check out some of the answers on this post two, Anthony answer near the end really cleared it up for me. Do some tests using the
Object getClass() method then you can really see what type the compiler thinks it is!
https://coderanch.com/t/239272/java-programmer-SCJP/certification/Dan-exam-ClassCastExceptionhinks
I was really confused since most of the sources don't explain it that well. Hope that helps!
[ September 15, 2002: Message edited by: Alan Phillips ]
 
Jose Botella
Ranch Hand
Posts: 2120
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Serena.
Base[] base = new Base[] {new Sub()};
Base[] base = {new Sub()};

both produce a ClassCastException because the runtime type of base is Base[]. Applying the last point in JLS 5.5:


If T is an array type TC[], that is, an array of components of type TC, then a run-time exception is thrown unless one of the following is true:
# TC and RC are the same primitive type.
# TC and RC are reference types and type RC can be cast to TC by a recursive application of these run-time rules for casting.


Now applying the following point in JLS 5.5 :


If R is an ordinary class (not an array class):
If T is a class type, then R must be either the same class (�4.3.4) as T or a subclass of T, or a run-time exception is thrown.


Because Base is not the same class or a subclass of Sub a ClassCastException is thrown.
However in:
Base[] base = new Sub[] {new Sub()};
the runtime type of base is Sub[] and Sub is the same type as Sub, thus no exception is thrown.
 
Ranch Hand
Posts: 1056
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Jose, I get no exception when running this code, nor would I expect to:

It is perfectly legal to store a Sub in a Base[] array.
 
Ranch Hand
Posts: 223
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
hi
Base[] base = {new Base()};
Sub sub[] = new Sub[1];
Object obj = base;
sub = (Sub[])obj;
this a downcasting problem.
obj has to denote an object related to Sub class or any of its subclasses if any and then the cast would be legal at runtime. if you try
Base[] base = {new Base()};
Sub[] sub,sub1 = new Sub[1];
Object obj = sub;
base = (Base[])obj;
I hope this would help.
 
Jose Botella
Ranch Hand
Posts: 2120
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
But Ron I meant any of my two lines intead of the fist one in
 
Ron Newman
Ranch Hand
Posts: 1056
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Oh, I see what you're saying. Once you've created an array as a Base[], you can't cast the array reference to a Sub[] , even if every element of the array is a Sub:

If the cast were allowed, you could then next do

and since subs and bases are pointing to the same array, subs[0] would contain a non-Sub. Not good.
reply
    Bookmark Topic Watch Topic
  • New Topic