Skip to content

Raw Types with Generic

hingen edited this page Oct 12, 2021 · 12 revisions

When declaring a variable or instantiating an object of a generic class, one might notice that Java does not produce any error if the type parameter is left out. Said syntax is valid as what you're doing is creating a variable or instantiating an object of a raw type.

ArrayList list = new ArrayList<Integer>();

Not Wildcards

When assigning to a variable of a raw type, the behaviour is similar to that of when a wildcard (?) is used as the type parameter.

// Wildcard example
ArrayList<?> list = new ArrayList<Integer>();
list = new ArrayList<String>();

// Raw type example
ArrayList list = new ArrayList<Integer>();
list = new ArrayList<String>();

However, do not be mistaken. Raw types are not the same as wildcards. Wildcards come with lots of restrictions that raw types do not have.

// Wildcard example
ArrayList<?> list = new ArrayList<Integer>();
list.add(1) // Will procuce an error

// Raw type example
ArrayList list = new ArrayList<Integer>();
list.add(1) // No error

Not Object

Base on code like the following, one might argue that perhaps raw types are just generic types that use the Object type parameter.

// Raw type example
ArrayList list = new ArrayList<Integer>();
list.add(1)
list.add("Hello")
list.add(1.3)
System.out.println(list) // Will print [1, Hello, 1.3]

However, this is wrong as raw types allow for even stranger behaviour.

ArrayList<String> list2 = list;
list.get(1) // No error as index 1 contains "Hello"
list2.get(0) // ClassCastException

I am able to assign list to a variable of type ArrayList<String>. An exception is only thrown when I try to access an items in list2 that isn't of type String.

Conclusion

Althought an absence of type restrictions might seem like a good thing for those coming from dynamic typed languages (e.g. python and javascript), this is actually extremely dangerous in a statically typed language like Java. It allows for "strange" code that breaks the conventions of statically typed languages, causing behaviours that most programmers would not expect. Raw types exist for backwards compatibility reasons and programmers should be careful to avoid explicity using them at all cost.

Clone this wiki locally