Raw Types in Java β Why to Avoid Them
A raw type is a generic class used without its type arguments β List instead of List<String>. Raw types exist only for backward compatibility with pre-Java-5 code. Modern code should never use them; doing so disables compile-time type checks and reintroduces the runtime casting errors generics were invented to prevent.
What raw means
List list = new ArrayList(); // raw β no type argument
list.add("hello");
list.add(42); // compiles β anything goes
String s = (String) list.get(1); // ClassCastException at runtime
Unchecked warnings
The compiler warns about every raw-type operation:
warning: [unchecked] unchecked call to add(E) as a member of the raw type List
warning: [rawtypes] found raw type: List
Silencing them with @SuppressWarnings without fixing the underlying issue papers over bugs.
Raw vs wildcard
public void rawApi(List list) { list.add("anything"); } // raw β unsafe
public void wildApi(List<?> list) { list.size(); } // wildcard β safe, read-only
List<?> means "a list of some unknown type" β you can't add to it (except null), but you can read from it as Object. It's the safe equivalent of a raw type when you truly don't know the element type.
Heap pollution
List raw = new ArrayList();
List<String> strings = raw; // unchecked
raw.add(42); // int in a "List<String>" β polluted
String s = strings.get(0); // ClassCastException later
Interop with legacy APIs
If you must consume a raw-type API (old library, unparameterised DTO), constrain the conversion at the boundary:
@SuppressWarnings("unchecked")
List<String> typed = (List<String>) legacyApi.fetch();
// Better: verify element-by-element if you have any doubt
for (Object o : legacyApi.fetch()) {
if (!(o instanceof String)) throw new ClassCastException();
}
Common mistakes
- Omitting type arguments from intermediate locals β
var list = new ArrayList<>();without context infersArrayList<Object>, not raw, but still not what you want. - Silencing unchecked warnings wholesale β hides real bugs. Narrow to the line.
- Public APIs returning raw types β punishes every caller. Parameterise.
Related
Pillar: Java generics. See also wildcards, type erasure.