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

add varargs array factory methods

    Details

    • Type: Enhancement
    • Status: Open
    • Priority: P5
    • Resolution: Unresolved
    • Affects Version/s: None
    • Fix Version/s: None
    • Component/s: core-libs
    • Labels:

      Description

      The language provides a convenient syntax for creating arrays, but only as a variable initializer. For example, one can write:

          int[] intArray = { 1, 2, 3 };

      instead of

          int[] intArray = new int[] { 1, 2, 3 };

      However, it is not possible to use this syntax in other locations, such as in a method argument list or
      on the right-hand side of an assignment. For example, consider a method that takes an array:

          void foo(int[] intArray) { ... }

      One cannot write

          foo({ 1, 2, 3 });

      and instead one must write

          foo(new int[] { 1, 2, 3 })

      This clutters up the argument list.

      The proposal is to consider adding a set of varargs "array factory" methods, probably to the java.util.Arrays class:

          static int[] of(int... array) { return array; }
          static long[] of(long... array) { return array; }
          static double[] of(double... array) { return array; }
          @SafeVarargs static <T> T[] of(T... array) { return array; }

      This would allow more convenient construction of arrays. For example, the above could be written as

          foo(Arrays.of(1, 2, 3))

      or even

         foo(of(1, 2, 3))

      if static imports are used.

      The element type of the reference array can be controlled with a type witness:

          CharSequence[] csa;
          ...
          csa = Arrays.<CharSequence>of("a", "b", "c");

      However, this is no shorter than just constructing a new array.

      The exact set of primitive overloads to be added is to be determined.

      It needs to be verified that the generic of() method is indeed @SafeVarargs.

      The method call Array.of(1, 2, 3) makes perfect sense, but if we expect static import
      to be used more frequently, a bare of(1, 2, 3) call looks odd. A different name could be
      used, for example, array(1, 2, 3).

        Activity

        Hide
        smarks Stuart Marks added a comment -
        For the generic case, the runtime component type of the array created must be considered.

        At first glance, T is erased, so one would expect that the array's component always to be Object. This is not the case. Javac's behavior is to infer the type T, presumably using normal inference rules, and then to create the array using the erasure of that type. Thus, Arrays.of("a", "b") will indeed result in an array of type String[]. (This is actually a bit surprising. It seems to have been a contributing cause of JDK-6260652.)

        It looks like JLS 15.12.4.2 covers this area. It appears that this behavior is allowed ("for some T ... as if "new |T[]| { en, ... , ek }") but it might not be required. In particular, it doesn't say how T is determined.

        Javac, at least, has behaved consistently in this regard since the introduction of varags (Java SE 5), so even if this exact behavior isn't required, it has a long history. It thus might not be too bad to rely on it even if it isn't required.
        Show
        smarks Stuart Marks added a comment - For the generic case, the runtime component type of the array created must be considered. At first glance, T is erased, so one would expect that the array's component always to be Object. This is not the case. Javac's behavior is to infer the type T, presumably using normal inference rules, and then to create the array using the erasure of that type. Thus, Arrays.of("a", "b") will indeed result in an array of type String[]. (This is actually a bit surprising. It seems to have been a contributing cause of JDK-6260652 .) It looks like JLS 15.12.4.2 covers this area. It appears that this behavior is allowed ("for some T ... as if "new |T[]| { en, ... , ek }") but it might not be required. In particular, it doesn't say how T is determined. Javac, at least, has behaved consistently in this regard since the introduction of varags (Java SE 5), so even if this exact behavior isn't required, it has a long history. It thus might not be too bad to rely on it even if it isn't required.

          People

          • Assignee:
            smarks Stuart Marks
            Reporter:
            smarks Stuart Marks
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated: