In a nutshell, generics enable types (classes and interfaces) to be parameters when defining classes, interfaces and methods. Much like the more familiar formal parameters used in method declarations, type parameters provide a way for you to re-use the same code with different inputs. The difference is that the inputs to formal parameters are values, while the inputs to type parameters are types.
Code that uses generics has many benefits over non-generic code:
List list = new ArrayList(); list.add("hello"); String s = (String) list.get(0);
List<String> list = new ArrayList<String>(); list.add("hello"); String s = list.get(0); // no cast