Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating an array to store generic types in Java [duplicate]

Tags:

java

generics

Suppose I have to create an array which stores ArrayList's of Integers and the array size is 10.

The below code will do it:

ArrayList<Integer>[] pl2 = new ArrayList[10];  

Question 1:

In my opinion the more appropriate code would be

ArrayList<Integer>[] pl2 = new ArrayList<Integer>[10];     

Why does this not work?

Question 2:

Both of the below compile

  1. ArrayList<Integer>[] pl2 = new ArrayList[10];
  2. ArrayList[] pl3 = new ArrayList[10];

What is the difference as far as the reference declaration of pl2 and pl3 is concerned?

like image 445
Geek Avatar asked May 07 '13 09:05

Geek


1 Answers

The generic info only matters in compile time, it tells the compiler which type could be put into an array, in runtime, all the generic info will be erased, so what matters is how you declare the generic type.

Quoted from Think in Java:

it’s not precisely correct to say that you cannot create arrays of generic types. True, the compiler won’t let you instantiate an array of a generic type. However, it will let you create a reference to such an array. For example:

List<String>[] ls;  

This passes through the compiler without complaint. And although you cannot create an actual array object that holds generics, you can create an array of the non-generified type and cast it:

//: arrays/ArrayOfGenerics.java  // It is possible to create arrays of generics.  import java.util.*;   public class ArrayOfGenerics {      @SuppressWarnings("unchecked")      public static void main(String[] args) {          List<String>[] ls;          List[] la = new List[10];          ls = (List<String>[])la; // "Unchecked" warning          ls[0] = new ArrayList<String>();          // Compile-time checking produces an error:          //! ls[1] = new ArrayList<Integer>();           // The problem: List<String> is a subtype of Object          Object[] objects = ls; // So assignment is OK          // Compiles and runs without complaint:          objects[1] = new ArrayList<Integer>();           // However, if your needs are straightforward it is          // possible to create an array of generics, albeit          // with an "unchecked" warning:          List<BerylliumSphere>[] spheres =             (List<BerylliumSphere>[])new List[10];          for(int i = 0; i < spheres.length; i++)             spheres[i] = new ArrayList<BerylliumSphere>();      }  } 

Once you have a reference to a List[], you can see that you get some compile-time checking. The problem is that arrays are covariant, so a List[] is also an Object[], and you can use this to assign an ArrayList into your array, with no error at either compile time or run time.

If you know you’re not going to upcast and your needs are relatively simple, however, it is possible to create an array of generics, which will provide basic compile-time type checking. However, a generic container will virtually always be a better choice than an array of generics.

like image 151
ltebean Avatar answered Sep 26 '22 02:09

ltebean