5

Why isn't List.toArray() generic? Why must you give the type as an argument (and usually create a new empty instance)?

public Object[] toArray()

http://docs.oracle.com/javase/7/docs/api/java/util/List.html#toArray()


Update: I have since learned that generic array creation is not allowed, but I believe that it should be. Is there any reason why it's not allowed?

Main.java:28: error: generic array creation
        T[] ret = new T[size()]; 

http://ideone.com/3nX0cz


Update: Ok I believe this is the answer:

http://docs.oracle.com/javase/tutorial/java/generics/restrictions.html#createArrays

Not because it is directly relevant, but indirectly relevant. There is nothing inherently wrong with new T[size()], where MyList<String> would be turned into new String[size()], but T could itself be a parameterized type. So if you were to create MyList<Set<Integer>>, then T would equal Set<Integer> and the compiler would try to create new Set<Integer>[size()], which could lead to the problem in the link when returned. Someone tried to give an answer along these lines but that answer has since been deleted so I forgot who it was.

9
  • 4
    There is an overloaded version of toArray that is generic Commented Oct 15, 2013 at 18:33
  • Scroll slightly further down. Commented Oct 15, 2013 at 18:34
  • @Dgrin91 But you have to pass in an array instance as a parameter, which is what the OP was asking about. Commented Oct 15, 2013 at 18:34
  • 3
    To maintain backward compatibility. Commented Oct 15, 2013 at 18:35
  • 1
    Possible duplicate of stackoverflow.com/questions/7909747/… Commented Oct 15, 2013 at 18:35

3 Answers 3

4

This method is supposed to create a new array. But, if you don't have the Class information of T, you cannot do that.

You cannot say T[] array = new T[list.size()];

If you pass the array as a parameter (like in the other method) there is no problem.

Sign up to request clarification or add additional context in comments.

Comments

1

The complete answer is: because the implementation of toArray() is not able to construct the T[] array it's supposed to return to you without the "exemplar" array. Look at the source code of the generic overload of toArray( T[] ) in AbstractCollection to see the difference.

They also could have done it with a Class< T > argument. But at least with an exemplar you can allocate the space yourself if you want to (and it's nearly impossible to produce an instance of Class< G< S > > for a generic type G< S >).

Comments

0

Because of the nature of Generics in Java. Due to erasure, there is no type information available during runtime, so the no-arg version can only return an array of Objects.

1 Comment

@GriffeyDog They couldn't change the return type unless also adding T parameter which is what Kayaman is saying. You are right that they created an overload to maintain backward compatibility since the original toArray() was there since 1.2 and the generic since only 1.5.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.