Here is a typical usage of that sort:
List myIntList = new LinkedList(); // 1 myIntList.add(new Integer(0)); // 2 Integer x = (Integer) myIntList.iterator().next(); // 3
Object will be returned by the iterator. To ensure the assignment to a variable of type Integer is type safe, the cast is required.
What if programmers could actually express their intent, and mark a list as being restricted to contain a particular data type? This is the core idea behind generics. Here is a version of the program fragment given above using generics:
List<Integer>
myIntList = new LinkedList<Integer>(); // 1'
myIntList.add(new Integer(0)); // 2'
Integer x = myIntList.iterator().next(); // 3'
Notice the type declaration for the variablemyIntList. It specifies that this is not just an arbitraryList, but aListofInteger, writtenList<Integer>. We say thatListis a generic interface that takes a type parameter--in this case,Integer. We also specify a type parameter when creating the list object.Note, too, that the cast on line 3' is gone.Now, you might think that all we've accomplished is to move the clutter around. Instead of a cast toIntegeron line 3, we haveIntegeras a type parameter on line 1'. However, there is a very big difference here. The compiler can now check the type correctness of the program at compile-time. When we say thatmyIntListis declared with typeList<Integer>, this tells us something about the variablemyIntList, which holds true wherever and whenever it is used, and the compiler will guarantee it. In contrast, the cast tells us something the programmer thinks is true at a single point in the code.