*
The moose likes Java in General and the fly likes Object[] to Long[] Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Android Security Essentials Live Lessons this week in the Android forum!
JavaRanch » Java Forums » Java » Java in General
Bookmark "Object[] to Long[]" Watch "Object[] to Long[]" New topic
Author

Object[] to Long[]

Jacob Sonia
Ranch Hand

Joined: Jun 28, 2009
Posts: 174
I have a Long[] array and a Set<Long> and i try to do this:

Long[] arr = (Long[])set.toArray();

It throws a ClassCastException. Please tell me why does it do that and how can i achieve what i am trying to do?
Tim McGuire
Ranch Hand

Joined: Apr 30, 2003
Posts: 820

Jacob Sonia wrote:I have a Long[] array and a Set<Long> and i try to do this:

Long[] arr = (Long[])set.toArray();

It throws a ClassCastException. Please tell me why does it do that and how can i achieve what i am trying to do?


arrays cannot be cast like other Objects as Long[] does not inherit from Object[].

one way to do it is:

Long[] arr = set.toArray(new Long[0]);

Check out http://java.sun.com/javase/6/docs/api/java/util/Set.html#toArray%28%29
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18545
    
  40

Jacob Sonia wrote:I have a Long[] array and a Set<Long> and i try to do this:

Long[] arr = (Long[])set.toArray();

It throws a ClassCastException. Please tell me why does it do that and how can i achieve what i am trying to do?


The toArray() method returns an Object[] with Long objects as it's elements. It doesn't return a Long[], hence, can't be casted. To make it return an Long[], use the other (overloaded) toArray() method.

Henry


Books: Java Threads, 3rd Edition, Jini in a Nutshell, and Java Gems (contributor)
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24183
    
  34

Tim McGuire wrote:

arrays cannot be cast like other Objects as Long[] does not inherit from Object[].



Although the rest of what Tim says is true, this actually is not: Long[] does inherit from Object[]. You can't do the cast for the same reason that you can't cast "new Object()" to a Long.

Many people consider this inheritance setup a flaw in the language -- the design of generics was specifically arranged to learn from this mistake and avoid the issues this inheritance causes.

[Jess in Action][AskingGoodQuestions]
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19655
    
  18

I wouldn't call it inheriting. It's not like Long[].class.getSuperclass() returns Object[].class; it returns Object.class. Long[] is a subtype of Object[] though, just as Long is a subtype of Object. The term subtype is a bit broader than subclass because it also handles arrays and interfaces. For instance, ArrayList is a subtype of List because it implements List.


SCJP 1.4 - SCJP 6 - SCWCD 5 - OCEEJBD 6
How To Ask Questions How To Answer Questions
Tim McGuire
Ranch Hand

Joined: Apr 30, 2003
Posts: 820

Thanks for this clarification. This reasoning of "Long[] is not subclass of Object[] therefore casting won't work" is repeated so often in other forums, so I'm trying to grasp this other explanation.

so... here is code from the java specifications concerning casting of arrays
(http://java.sun.com/docs/books/jls/second_edition/html/conversions.doc.html#20232):



it says the above will compile and run. It does (well, except for there being two public types).
and this is a case of an array being cast to an array of subtypes! This does not seem to be different from our original problem as the Objects I get from
set.toArray()
resolve to type Long. and If I iterate through the array, they can be cast individually to Long.

the specs say that unless the following is true, there will be a runtime classCastException

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.


so this recursive application of run time casting rules DOES happen. I thought it didn't.

so set.toArray() returns an array of Objects that can be cast to Long through a "recursive application of run-time rules for casting", right?

Now that I've talked myself out of my original answer, I do not understand why he gets a classCastException.
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19655
    
  18

Try changing line 21 to "Point[] pa = new Point[4];" and try again.

You can cast an Object[] to a Long[] if the Object[] is in fact a Long[]. If it is an Object[] where each element happens to be a Long it will still fail, even though the elements match the cast.
Tim McGuire
Ranch Hand

Joined: Apr 30, 2003
Posts: 820

Rob Prime wrote:Try changing line 21 to "Point[] pa = new Point[4];" and try again.


I see, so inside of set.toArray() it is doing:



on line four, the method has no way to extract the type from it.next and use it, which is why we get the casting error.
and here it is obvious, as Ernest said, that having no type safety hurts, hence generics and the generic version of toArray fixes our problems.
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19655
    
  18

Tim McGuire wrote:
Rob Prime wrote:Try changing line 21 to "Point[] pa = new Point[4];" and try again.


I see, so inside of set.toArray() it is doing:

Something like that (this won't compile because of x missing).

on line four, the method has no way to extract the type from it.next and use it, which is why we get the casting error.

Not quite. The exception is not caused by anything inside the method, but after it has returned, because the array is an Object[] (as created at the top), not a Long[]. The trouble is line 1, but you got the reason right.
 
It is sorta covered in the JavaRanch Style Guide.
 
subject: Object[] to Long[]
 
Similar Threads
voucher issue
How did you find Javaranch?
What Cert to Pursue?
How long does it take to prepare SCJD in general?
Parsing an Int