 <blockquote> <p>However I would still expect the compiler to have enough information to compile the above piece of code.</p> </blockquote> <p>No it doesn't. Because you didn't gave the compiler enough information. </p> <p>You are using a raw type <code>Wrapper</code> in your code, in which case, all the generic type information is not available to the compiler. So, the compiler sees <code>ArrayList&lt;Wrapper&gt;</code> as just <code>ArrayList</code>, and that is why when you iterate over it, you'll get back <code>Object</code> type values and not <code>Wrapper</code> type.</p> <p>See <a href="http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.8" rel="nofollow">JLS &sect; 4.8 - Raw Types</a> for more details:</p> <blockquote> <p>The type of a constructor (§8.8), instance method (§8.4, §9.4), or non-static field (§8.3) M of a raw type C that is not inherited from its superclasses or superinterfaces is the raw type that corresponds to the erasure of its type in the generic declaration corresponding to C.</p> </blockquote> <p><strong>Also See:</strong></p> <ul> <li><a href="http://stackoverflow.com/q/2770321/1679863">What is a raw type and why shouldn&#39;t we use it?</a></li> </ul>