Skip to content

Raw Types with Generic

Russell Saerang edited this page Oct 13, 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. Said restrictions make wildcards a lot safer to use.

// 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

Based on code like the following, one might assume that raw types are just generic types that use the Object type parameter.

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

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

However, they would be mistaken as raw types allow for even stranger behaviour.

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

Assigning list, an ArrayList<Integer> object, to list2, a variable of type ArrayList<String>, is allowed. An exception is only thrown when trying to access any items in list2 that isn't of type String.

Conclusion

Although an absence of type restrictions might seem enticing 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