Generics allow us to specify the type of data a class, interface, or method will work with.
For example, without generics:
ArrayList list = new ArrayList();
list.add("Java");
list.add(100);
The same list can contain different types, which can cause problems later.
With generics:
ArrayList<String> list = new ArrayList<>();
list.add("Java");
list.add("Python");
Now the list is specifically for String.
If you try:
list.add(100);
Java gives a compile-time error.
So the basic idea is:
Generics allow us to tell Java what type of data a class or method should work with.
The <String> part is the type parameter:
ArrayList<String>
↑
type parameter
The main reasons are: