The oracle documentation states that generics enable types (classes and interfaces) to be parameters when defining classes, interfaces, and methods.

Before generics were introduced into the language, the compiler had a much harder time identifying errors due to type restrictions and you had to cast your objects when pulling them from data structures such as Lists. An example of this:

without generics, needs cast:

List list = new ArrayList();
list.add(“hello”);
String s = (String) list.get(0);

with generics:

List<String> list = new ArrayList<String>();
list.add(“hello”);
String s = list.get(0);

Because our underlying data structures are generic you might try to instantiate a generic array like this:

E[] arr = new E[size];

This is not possible.

This is because when the code runs, the type E is "not known" (this is called type erasure). This idea works in many other languages, but it doesn’t work in Java. Other languages will compile each generic use into a custom class. For example, in C++ a vector of int, a vector of char, and vector of Shape would each end up having a custom class.

Instead, when instantiating a new generic array, you should use the following code:

Generic Casting
Note
we add the @SuppressWarnings("unchecked") because this code will cause a warning. Unchecked casting is normally dangerous. Do you think there is a situation where this code could be dangerous?

Writing code that generates warnings can desensitize you to the bad idea of writing code that generates warnings. Don’t leave in warning-generating code unless you understand exactly why that code is there and why it is unavoidable. Generic code that uses arrays is one such justifiable circumstance; you are unlikely to encounter many others.

To learn more about generics, which I highly encourage, go here.