wood burning stoves*
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes casting between a ref type and an array. Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of OCM Java EE 6 Enterprise Architect Exam Guide this week in the OCMJEA forum!
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "casting between a ref type and an array." Watch "casting between a ref type and an array." New topic
Author

casting between a ref type and an array.

vivek rai
Ranch Hand

Joined: May 08, 2000
Posts: 45
Hi gurus,
This might be slightly off the mark.. and bit of a theoretical question.. anyway..
the JLS says... ( chap 5.. Conversions etc.., sec 5.5 )
"The detailed rules for compile-time correctness checking of a casting conversion of a value of compile-time reference type S (source) to a compile-time reference type T (target) are as follows:
If S is a class type:
If T is an array type, then S must be the class Object, or a compile-time error occurs. "

now, my question is: any Class can be cast as Object, So basically any class can be coverted to some array of some other class without any compile-time array by casting it in two steps..i.e, cast to Object first and then to the array type.
for example,
-----
class Point { int x,y; }
class SomeClass {}
public class Test
{
public static void main ( String [] args )
{
Point p = new Point();
SomeClass asc[] = new SomeClass[5];
// this compiles
asc = ( SomeClass[] ) ( ( Object ) p );
// this gives the compiler error
/* Invalid cast from Point to SomeClass[].
asc = ( SomeClass[] ) ( p );
*/
asc = ( SomeClass[] ) ( p );
}
}
----
So what is really meant by the statement given in JLS? Is it incorrect, or has it to be interpreted as for being for a single cast operation?
Am I missing something here?
regards,
vivek
Herbert Maosa
Ranch Hand

Joined: May 03, 2000
Posts: 289
I have tried to go through your code. The statement under discussion, and indeed the rules governing safe compile time and run time casting are quite diverse and it is not feasible for me to discuss them all here. However as regards casting arrays note the following :
1. You can never safely cast a reference to an array into anything but a reference to an object of Class class or another array. Thus you can only do something like :
a) Object someObject = (Object)somearray; or
b)SomeArrayType = (SomeArrayType)anotherArray.
Note that in the case of a), then you can safely just convert without explicit casting.
In the case of b, it will only compile successfully IFF
a)Both anotherArray and SomeArray contain object references AND
b)The object references in anotherArray are such that they can be safely cast into the references contained in SomeArrayType.
This could not be the best explanation, but if you follow it openly I believe it should shed more light on what that statement in JLS means.
Regards,
Herbert
Ajith Kallambella
Sheriff

Joined: Mar 17, 2000
Posts: 5782
Here are my two cents worth..
The type of the Object is the class type that is used during its creation. The object continues to carry that identity all through its life.
In your example, type of p is Point. Simply by casting p to Object, you are only satisfying the compiler. That's why your first cast asc = ( SomeClass[] ) ( ( Object ) p ); works fine.
Remember, the type of p is still Point and not Object. So, when you try the next statement asc = ( SomeClass[] ) ( p ); the compiler balks because p cannot be treated in place of an object of type Object.
We only cast references, we don't cast objects. A reference is simply looking at an object from a different( but coherent ) perspective. An object once created, its class type cannot be changed.
Ajith


Open Group Certified Distinguished IT Architect. Open Group Certified Master IT Architect. Sun Certified Architect (SCEA).
Herbert Maosa
Ranch Hand

Joined: May 03, 2000
Posts: 289
Ajith,
I just want to further this discussion with you and reach a consesus. I quote the following from your explanation:
-----------------------------------------------------------------
In your example, type of p is Point. Simply by casting p to Object, you are only satisfying the compiler. That's why your first cast asc = ( SomeClass[] ) ( ( Object ) p ); works fine.
Remember, the type of p is still Point and not Object. So, when you try the next statement asc = ( SomeClass[] ) ( p ); the compiler balks because p cannot be treated in place of an object of type Object.
-----------------------------------------------------------------
I basically agree with this, save a few points. It is true that p is of type Point, and so it will remain for its entire lifetime.However I think that the reason that the statement:
asc =(someClass[])(p) fails to compile has nothing to do with the true class of p. I say this because the resolution of the true class for p is a run time issue, not compile time. This will fail to compile because we are attempting to cast between an array and an object reference which is neither an array of compatible type nor of the class Object, the only legal ways for safe array casting.
Think about this.
Herbert
Anonymous
Ranch Hand

Joined: Nov 22, 2008
Posts: 18944
FYI, a few basic rules to remeber
Reference conversion and casting happen at both compile and
run time. Conversion is up the inheritance tree. Casting is
down inheritance tree. Apply common sence.

Object Reference conversion ( at compile time)
1. interface oldtype may convert to newtype. if newtype is a superinterface of oldtype.
2. class oldtype may be converted to newtype. if newtype is a superclass of oldtype.
3. array oldtype may be converted to newtype. if both types are arrays contain object references and #2 above applies.
Object Reference casting ( at compile time)
4. interface oldtype can always be cast to newtype. if newtype is a non-final object.
5. class oldtype may be cast to newtype. if newtype is a subclass of oldtype
6. array oldtype may be cast to newtype. if if both arrays contain object references and #5 above applies.
* the class type for an object can NOT be determined at compile time.
Object Reference casting ( at run time)
7. if newtype is a class. the newtype must inherit from oldtype.
8. if newtype is an interface. the class of the expression being implemented must implement newtype.

Hope this clear up any outstanding issues.


[This message has been edited by monty6 (edited May 24, 2000).]
[This message has been edited by monty6 (edited May 24, 2000).]
[This message has been edited by monty6 (edited May 24, 2000).]
 
Don't get me started about those stupid light bulbs.
 
subject: casting between a ref type and an array.