-1

I know that array generic array creation is not allowed because arrays need to know their type at run-time but since generic erase their type information at run-time it is not possible to create generic array. But how come it allows generic array declaration as follow :

private E[] genericArray;// this line does not prevent the class from compiling

private E[] genericArrayTwo= new E[][10];// this line prevents the class from compiling
davidxxx
  • 125,838
  • 23
  • 214
  • 215
kaka
  • 597
  • 3
  • 5
  • 16
  • Why would it not be allowed? Note that a field declaration of an array is initialized to `null` by default, so there's no need to know the element type. – Jorn Vernee Jun 22 '19 at 14:17

2 Answers2

1
private E[] genericArray;// this line does not prevent the class from compiling

private E[] genericArrayTwo= new E[][10];// this line prevents the class from compiling
  • Your first example was compile time evaluation to ensure proper typing. Simply says that this array may contain something of type E.
  • Your second example would need to be executed at run time when E has already been erased. Can't create an array of type E because E is no longer available.

Allowing generic array declarations ensures that appropriate types are matched at compile time.

      Integer[] ints1 = null;
      String[] str1 = null;

      // both requires cast or it won't compile
      Integer[] ints = (Integer[])doSomething1(ints1);
      String[] str = (String[])doSomething1(str1);

      //but that could result in a runtime error if miscast.
      //That type of error might not appear for a long time

      // Generic method caters to all array types.
      // no casting required.
      ints = doSomething2(ints1);
      str = doSomething2(str1);

   }

   public static Object[] doSomething1(Object[] array) {
      return array;
   }

   public static <T> T[] doSomething2(T[] array) {
      return array;
   }

It allows examples such as the following:

public <T> void copy(List<T> list, T[] array) {
   for (T e : array) {
      list.add(e);
   }
}

You could then assign a value from either the list or the array to some variable of type T without getting a class cast exception or without having to to an instanceof test.

WJS
  • 36,363
  • 4
  • 24
  • 39
  • "Allowing generic array declarations ensures that appropriate types are matched at compile time" could you please explain this point? – kaka Jun 22 '19 at 15:06
0

If E is a formal generic of the current class, yes you can do that :

List<E> e = new ArrayList<E>();

but you cannot do that :

E[] e = new E[10];

But declaring the E[] e variable makes sense all the same.

because no one prevents you from valuing the array from the client side that knows the real type of the array :

Foo<E> class{        
    private E[] array;
    Foo(E[] array) {
        this.array = array;
    }
}

And to use it as :

Foo<String> foo = new Foo<>(new String[] { "a", "b" });

Or as alternative you could also pass the class of the array to instantiate from the client side :

Foo<String> foo = new Foo<>(String.class);

So you see that declaring E[] array is not so helpless.

davidxxx
  • 125,838
  • 23
  • 214
  • 215