These lines
Sample s = new Sample();
// Why this doesn't work?
for (String string : s.getStringList()) {
}
do not work because you are using the raw form of the Sample
class. When you use the raw form of the class, all generics in the class, even unrelated generics, have type erasure performed. That means that getStringList
now just returns a List
of Object
s, not a List<String>
of String
s.
This part of Java was introduced with Generics in Java 1.5 so that the old version of classes that now use generics would be backwards compatible. That way, something that iterates over List
, which had to use Object
before, still can use Object
by using the raw form of List
.
The JLS, Section 4.8 deals with raw types:
More precisely, a raw type is defined to be one of:
- The reference type that is formed by taking the name of a generic type declaration without an accompanying type argument list.
and
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.
(emphasis mine)
The reasoning:
The use of raw types is allowed only as a concession to compatibility of legacy code. The use of raw types in code written after the introduction of generics into the Java programming language is strongly discouraged. It is possible that future versions of the Java programming language will disallow the use of raw types.