Some limitations of Java generic types

 

Because generic types are eliminated at runtime, there are some restrictions on how generic types can be used.

Restriction 1: cannot use new E()

Instances cannot be created with generic type parameters. For example, the following statement is wrong:

 

Restriction 2: new E[] cannot be used

  Arrays cannot be created with generic type parameters. For example, the following statement is wrong.

  E[] elements = new E[capacity];

  This limitation can be circumvented by creating an array of type Object and then casting it to E[] as follows:

  E[] elements = (E[]) new Object[capacity];

  However, casting to (E()) results in an unchecked warning. This warning occurs because the compiler cannot ensure that the type conversion will succeed at runtime. For example, if E is String and new Object[] is an array of Integer objects, then (String[])(new Object[]) will result in a ClassCastException. This type of compilation warning is a limitation of Java generics and cannot be avoided.

 

  Generic arrays cannot be created using generic classes. For example, the following code is wrong:

  ArrayList<String> list = new ArrayList<String>[10];

  This limitation can be circumvented by using the following code:

  ArrayList<String> list = (ArrayList<String>[]) new ArrayList[10];

  You will get a compile warning.

Restriction 3: Class parameters are not allowed to be generic types in a static environment

  Since all instances of a generic class have the same runtime class, the static variables and methods of a generic class are shared by all its instances. Therefore, it is illegal to refer to a generic type parameter for the sake of a class in a static method, data field, or initialization statement. For example, the following code is illegal:

  public class Test<E> {

    public static void m(E o1) {  // Illegal

    }

    public static E o1;  // Illegal

    static {

      E o2; // Illegal

    }

  }

Restriction 4: Exception classes cannot be generic

  Generic classes cannot extend java.lang.Throwable, so the following class declaration is illegal:

  Why? If this is allowed, add a catch clause to MyException<T> as follows:

  public class MyException<T> extends Exception {

  }

  The JVM must check this exception thrown from the try clause to see if it matches the type specified in the catch clause. But this is not possible because the type information is not present at runtime.

  try {

  ...

  }

  catch (MyException<T> ex) {

  ...

  }

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324650722&siteId=291194637