File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes what does List.toArray(T[]) return? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of EJB 3 in Action this week in the EJB and other Java EE Technologies forum!
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "what does List.toArray(T[]) return?" Watch "what does List.toArray(T[]) return?" New topic
Author

what does List.toArray(T[]) return?

James Quinton
Ranch Hand

Joined: Oct 02, 2006
Posts: 94
I thought, according to API, List.toArray(T[]) should return T[], but actually not.
It still returns Object[], unless you specify a generic type for this List. e.g.

this works well:
List<Integer> list = new ArrayList<Integer>();
Integer[] arr = list.toArray(new Integer[0]);

But, if you just define:
List list = new ArrayList();

this won't even compile:
Integer[] arr = list.toArray(new Integer[0]);
It complains incorrect conversion from Ojbect[] to Integer[].

Since API defines List interface as
public interface List<E>
I thought generic type <E> had nothing to do with generic method type <T>:
<T> T[] toArray(T[] a)

But actually, T is determined by E.

Do I think too much, or am I crazy?
Keith Lynn
Ranch Hand

Joined: Feb 07, 2005
Posts: 2367
In the second code, you need to cast the result of the toArray method to the appropriate type of array.

When you parameterize the List, you don't have to cast.
James Quinton
Ranch Hand

Joined: Oct 02, 2006
Posts: 94
you can NOT cast Object[] to Integer[]
Integer[] is not subtype of Object[]
Keith Lynn
Ranch Hand

Joined: Feb 07, 2005
Posts: 2367
Keith Lynn
Ranch Hand

Joined: Feb 07, 2005
Posts: 2367
James Quinton
Ranch Hand

Joined: Oct 02, 2006
Posts: 94
i got runtime ClassCastException.
anyway, i figured it out.

still the question is why does toArray(T[] a) return Object[], not T[] if generic type is not provided?
[ November 08, 2006: Message edited by: James Quinton ]
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
[James]: you can NOT cast Object[] to Integer[]
Integer[] is not subtype of Object[]


For better or worse, yes you can cast it. Java treats Integer[] as a subtype of Object[] - even though this can create some problems, since for example you can put a String in an Object[], but not in a Integer[]. Nonetheless, this both compiles and runs:

In general though, you can save yourself a lot of headaches by not attempting to use raw types like this.


"I'm not back." - Bill Harding, Twister
Keith Lynn
Ranch Hand

Joined: Feb 07, 2005
Posts: 2367
If the actual runtime type of the array is Object[], then you can't cast it. But if the runtime type is Integer[], but it is currently referred to as an Object[] or Number[], you can cast it to an Integer[].

Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
[James]: still the question is why does toArray(T[] a) return Object[], not T[] if generic type is not provided?

Good question. On the surface, E and T are defined independently. The answer is mostly found in
JLS 15.12:
The result type of the chosen method is determined as follows: [...] if unchecked conversion was necessary for the method to be applicable then the result type is the erasure (�4.6) of the method's declared return type.

Now it's not immediately apparent that unchecked conversion was needed at the line in question. However in order to determine applicability of a method, the type of the target reference must be determined. And in this case, that required unchecked conversion from List<E> to List. Basically, once you use a raw type somewhere, it tends to pervasively erase types on anything it touches.
James Quinton
Ranch Hand

Joined: Oct 02, 2006
Posts: 94
ok, then.
a little bit off topic: If Integer[] is the subtype of Object[], what are the exact class types of Integer[] and Object[]?
Is an array supposed to be Object type? If so, why Integer[] cannot be cast to String[] at compile time?
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
[James]: a little bit off topic: If Integer[] is the subtype of Object[], what are the exact class types of Integer[] and Object[]?

They're Integer[] and Object[] - exactly that.

[James]: Is an array supposed to be Object type?

All arrays are subtypes of Object, yes.

[James]: If so, why Integer[] cannot be cast to String[] at compile time?

For much the same reason that an Integer cannot be cast to a String at compile time. I'll discuss that first because it's simpler and more likely to be familiar. An Object reference can be cast to either Integer or String, because the compiler knows that a variable of reference type Object could hold a reference to a subtype, such as Integer or String. So the compiler will insert the cast, and at runtime the JVM will check if it's valid or not, based on the actual type of the object referenced by the variable. However, a variable of type Integer could not possibly hold a reference to a String - so if you try to cast it, the compiler will simply give you an error right away, rather than waiting until runtime. Although Integer and String are both subtypes of Object, they are otherwise unrelated - and neither one is a subtype of the other. An Integer is not a String, and a String is not an Integer. Casting between the two is impossible.

In much the same way, Integer[] and String[] are subtypes of Object[] - but other than that, they are unrelated, because Integer and String are unrelated. You could take the preceding paragraph and replace every Object, Integer and String with Object[], Integer[] and String[] - the logic works just the same. An Integer[] is not a String[], and a String[] is not an Integer[]. There's no way a reference of one type could possibly refer to an instance of the other, so casting is impossible.
Dan Polak
Ranch Hand

Joined: Nov 06, 2006
Posts: 32
Look man

In order to use generic method you have to instance object as generic
if you dont T means Object

class Dupa<E> {
<T> T jo(T t) {
return t;
}
}

wont compile
Dupa d = new Dupa();
Integer i = d.jo(new Integer(1));


compile
Dupa<String> d = new Dupa<String>();
Integer i = d.jo(new Integer(1));


instead of String you can use any Type


<a href="http://www.dantheman.pl" target="_blank" rel="nofollow">http://www.dantheman.pl</a>
Dan Polak
Ranch Hand

Joined: Nov 06, 2006
Posts: 32
look again thats very interesting

and maybe will help you

class Dupa<E> {
<T extends Number> T jo(T t) {
return t;
}
}

wont compile
Dupa d = new Dupa();
Integer i = d.jo(new Integer(1));

compile

Dupa<String> d = new Dupa<String>();
Integer i = d.jo(new Integer(1));

regards
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: what does List.toArray(T[]) return?
 
Similar Threads
getting Class cast exception
List interface toArray method
Simple J2SE 5.0 Tiger Notes
Generics questions
How do you create an array of typesafe-collections?