Java Language Generics

30% OFF - 9th Anniversary discount on Entity Framework Extensions until December 15 with code: ZZZANNIVERSARY9


Generics are a facility of generic programming that extend Java's type system to allow a type or method to operate on objects of various types while providing compile-time type safety. In particular, the Java collections framework supports generics to specify the type of objects stored in a collection instance.


  • class ArrayList<E> {} // a generic class with type parameter E
  • class HashMap<K, V> {} // a generic class with two type parameters K and V
  • <E> void print(E element) {} // a generic method with type parameter E
  • ArrayList<String> names; // declaration of a generic class
  • ArrayList<?> objects; // declaration of a generic class with an unknown type parameter
  • new ArrayList<String>() // instantiation of a generic class
  • new ArrayList<>() // instantiation with type inference "diamond" (Java 7 or later)


Generics are implemented in Java through Type erasure, which means that during runtime the Type information specified in the instantiation of a generic class is not available. For example, the statement List<String> names = new ArrayList<>(); produces a list object from which the element type String cannot be recovered at runtime. However, if the list is stored in a field of type List<String>, or passed to a method/constructor parameter of this same type, or returned from a method of that return type, then the full type information can be recovered at runtime through the Java Reflection API.

This also means that when casting to a generic type (e.g.: (List<String>) list), the cast is an unchecked cast. Because the parameter <String> is erased, the JVM cannot check if a cast from a List<?> to a List<String> is correct; the JVM only sees a cast for List to List at runtime.

Got any Java Language Question?