Since Java 5 with the introduction of generics you could specify the type of a list.
That way the compiler makes sure you don't accidentaly add an object of different type than expected as well as you get the right one back when you ask for it.
However, you are still limited to the inherited type of the object you add.
Instead with a heterogenous container you get the actual type back.
The only difference is that the index of your list now becomes the type rather an int specifying its position.
T extends E
merely specifies that any type requested must be a subclass of the type specified in the list. This saves you from passing arbitrary types, yet you still need to accommodate asking for valid types that aren't added to the list.
In the posts to come we'll explore the possibilities of such containers.