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

(array) Retrofit arrays to become fully-fledged Collections

XMLWordPrintable

    • Icon: Enhancement Enhancement
    • Resolution: Fixed
    • Icon: P4 P4
    • None
    • 1.3.1
    • core-libs



      Name: nt126004 Date: 03/18/2002


      FULL PRODUCT VERSION :
      java 1.3.1-b24

      FULL OPERATING SYSTEM VERSION :
      N/A

      A DESCRIPTION OF THE PROBLEM :
      This language change seems an obvious idea with very
      significant benefits - not least a simplification of the
      language (most language changes produce a complication). It
      may also be possible without changing the JVM. However I've
      never come across the idea so maybe there is a big
      technical problem somewhere.

      When we have generic types (JSR-14), arrays of reference
      types could be made to implement the List interface, which
      would allow them to be passed to functions which expect a
      List or Collection. Currently there are many APIs which
      take arrays (for speed) and Lists/Vectors (for
      flexibility), and lots of code has to awkwardly convert
      between the two representations. Basically after JSR-14,
      Java will have **two** systems of parameterized types (the
      original one being arrays), and **two** systems of
      collections (arrays being the original ones). This proposal
      could hopefully merge the two without breaking existing
      code.

      In a nutshell, arrays of reference types (not primitive
      types) could, at the language level, pretend to be
      specializations of a new generic class Array<T> derived
      from List. This class could reveal all of the existing
      magic behaviour of arrays (their derivation from Object,
      that strange 'length' field, their Cloneability and
      Serializability, etc.) like any other API. Something like
      this:

      public final class java.util.Array<T> extends
      AbstractList<T> implements Cloneable, Serializable,
      RandomAccess {
      public final int length;
      // same as size()
      public Array<T>(int size);
      // same as new T[size]
      public Array<T>(Collection<T>); // might be useful; simpler than Collection.toArray(T[])

      public Object clone();
      public boolean contains(Object o);
      // from Collection interface
      public T get(int index);
      // from List interface; same as this[index]
      public Iterator<T> iterator();
      // from Collection interface
      public int size();
      // from Collection interface; same as this.length
      // etc. etc. (various other methods from
      the Collection/List interfaces)
      }

      All arrays of reference types (not primitive types) would
      appear to be instances of this class. Array operations
      using the [] syntax could be regarded as 'syntactic sugar'
      for normal method and constructor calls. E.g.
      String[] names = new String[10];
      names[0] = "Fred";
      String x = names[0];

      would be equivalent to:
      Array<String> names = new Array<String>(10);
      names.set(0,"Fred");
      String x = names.get(0);

      Of course, everybody would normally use the [] syntax, but
      the bonus is that you could pass a normal array to a method
      which expected a List, without either writing a separate
      method or converting to/from a List. For code using arrays
      or Arrays directly (as opposed to via the List interface),
      the compiler would produce the same bytecode as before
      (i.e. using the various array bytecodes).

      The Array<T> class would implement the other useful methods
      of List such as indexOf(Object), iterator() etc. List
      specifies several optional operations which Array would not
      implement because arrays aren?t resizable: add, addAll,
      clear, remove, removeAll, retainAll. So these would all
      throw the UnsupportedOperationException.

      A separate but closely-related proposal would be to make it
      easy for existing array code to be rewritten to take Lists
      instead. This could be done by a form of simple operator
      overloading, whereby List code could use the [] syntax as
      an alternative to calling get and set. Instead of adding
      new operator[] methods to List (which would be changing an
      existing interface), the compiler could just translate []
      into a get or set method call, so you could use the []
      syntax with any class which has set/get methods, not just
      Lists. In effect, get() and set() would be the official
      operator overloading method names for [], equivalent to
      C++'s operator[] (). For instance:
      LinkedList<Cat> cats = new LinkedList();
      cats.add(new Cat("Fred"));
      Cat myCat = cats[0]; // calls LinkedList.get
      cat[0] = new Cat("Jim"); // calls
      LinkedList.set

      As well as providing this very useful syntax, existing
      array code could be generalized to use Lists instead, with
      only a few minor changes (e.g. the use of the length
      variable, System.arraycopy() etc.).

      The biggest problem I can see with Array<T> this is that
      the rules for generics are more restrictive than for arrays:
      Cat[] cats = new Cat[10];
      Animal[] animals = cats; // legal

      List<Cat> cats = new List<Cat>(10);
      List<Animal> animals = cats; // illegal
      according to JSR-14

      But maybe this isn?t a problem and the Array class can
      allow this special behaviour?
      Array<Cat> cats = new Array<Cat>(10);
      Array<Animal> animals = cats; // make this case legal?

      I don't really know the implications of this. Here are some
      other issues. Multidimensional arrays: maybe these will
      just work, i.e. String[][] is the same as
      Array<Array<String>>. Reflection on Arrays: this would have
      to give the same results as for existing arrays ? maybe
      this is a problem.

      For what it's worth, this change could precipitate a tidy-
      up of the existing Arrays class, whose static methods for
      sorting, searching etc. would be no longer be needed, as
      they are already implemented by the Collections class as
      operations on Lists. Or we could add non-static methods for
      sort() etc. to class Array<T>. Oddities like
      System.arraycopy could also be made non-static methods of
      Array<T>.

      (As for arrays of primitive types, these obviously could
      not be specializations of Array<T>. They could be left
      untouched, or possibly pretend to be instances of a new set
      of classes FloatArray, IntArray etc. The benefits of this
      are less clear, other than generally tidying everything
      into the class hierarchy. I suppose these classes could
      have a base class PrimitiveArray with useful functions for
      sorting etc. to avoid the kind of static functions we find
      in the Arrays class.)


      This bug can be reproduced always.
      (Review ID: 139266)
      ======================================================================

            Unassigned Unassigned
            nthompsosunw Nathanael Thompson (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: