Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-7023484

add typesafe static Collections.toArray(Collection<? extends T>, IntFunction<T[]>)

    XMLWordPrintable

Details

    • Enhancement
    • Resolution: Unresolved
    • P4
    • None
    • None
    • core-libs

    Description

      A DESCRIPTION OF THE REQUEST :
      java.util.Collection defines method <T> T[] toArray(T[] a);

      Unfortunately, this is not compile-time type-safe, which can be seen in the test case below. The problem is that the signature of the method doesn't refer to the type parameter <E> of Collection.

      The correct signature of toArray(..) would be something like this, but this is not valid in Java: <T super E> T[] toArray(T[] a);

      Since I don't think Collection#toArray(T[]) can be fixed, I suggest a type-safe helper method in the java.util.Collections class:

      /**
      * Returns an array containing all of the elements in the given collection. This is a
      * compile-time type-safe alternative to {@link Collection#toArray(Object[])}.
      *
      * @param collection the source collection
      * @param clazz the type of the array elements
      * @param <A> the type of the array elements
      * @return an array of type <code>A</code> containing all of the elements in the given
      * collection
      * @throws NullPointerException if the specified collection or class is null
      */
      public static <A> A[] toArray(Collection<? extends A> collection, Class<A> clazz) {
      Object array= Array.newInstance(clazz, collection.size());
      @SuppressWarnings("unchecked")
      A[] typedArray= collection.toArray((A[]) array);
      return typedArray;
      }



      JUSTIFICATION :
      1.6 code like this compiles fine but throws an ArrayStoreException at run time:
              Integer[] ints = nums.toArray(new Integer[nums.size()]);

      With the suggested method, clients see the type safety problem at compile time:
              Integer[] ints = Collections2.toArray(nums, Integer.class);

      An added benefit of the new method is that the client doesn't have to write boilerplate code to create an array of a specific type.


      ---------- BEGIN SOURCE ----------
      import java.util.*;

      public class ArrayTypeBreak {
          public static void main(String[] args) {
              Collection<Number> nums = new ArrayList<Number>();
              nums.add(new Integer(1));
              nums.add(new Long(-1));
              
              Object[] objs = nums.toArray(new Object[0]);
              Object[] objs2 = nums.toArray(new Number[0]);
              Number[] nums2 = nums.toArray(new Number[0]);

              // No compile-time warning, but throws ArrayStoreException:
              Integer[] ints = nums.toArray(new Integer[nums.size()]);
              
              for (Integer integer : ints) {
                  System.out.println(integer);
              }
          }
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Clients can use a home-made helper method. However, such basic functionality should be shared in the JRE.

      Attachments

        Issue Links

          Activity

            People

              smarks Stuart Marks
              webbuggrp Webbug Group
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

                Created:
                Updated:
                Imported:
                Indexed: