I am really confused now.As far as i know if we don't use generics,we always get an Object type from a Collection and we need to cast it to the appropriate type.
When a subclass overrides a method, then it will be the subclass' method that will be invoked, when that method is called -- and this is true regardless of the type of the reference (subclass or superclass) used to access the object.
So... it doesn't matter if it is an Object reference, or an Integer reference. The actual object is an Integer object, and it is the toString() method of the Integer class that will be called, regardless of the reference, and / or any casting.
The above statement in your code is analagous to Object o = new Integer (2) ; Even though iterator.next() returns an object with an Object reference, it is still an Integer object. Hence the Integer version of toString executes. This is due to inheritance.
This results in a compiler error because you are equating a primitive with an object. During Autoboxing the compiler is looking for the reference type rather than the actual object you are passing through. Hence the casting.