A generic class or interface used without specifying a concrete type, called a raw type, enables backward compatibility with earlier versions of Java. You can use a generic class without specifying a concrete type like this:
GenericStack stack = new GenericStack(); // raw type
This is roughly equivalent to
GenericStack<Object> stack = new GenericStack<Object>();
A generic class such as GenericStack and ArrayList used without a type parameter is called a raw type. Using raw types allows for backward compatibility with earlier versions of Java. For example, a generic type has been used in java.lang.Comparable since JDK 1.5, but a lot of code still uses the raw type Comparable, as shown in the code below:
Comparable o1 and Comparable o2 are raw type declarations. Be careful: raw types are unsafe. For example, you might invoke the max method using
Max.max("Welcome", 23); // 23 is autoboxed into new Integer(23)
This would cause a runtime error, because you cannot compare a string with an integer object. The Java compiler displays a warning on line 3 when compiled with the option –Xlint:unchecked, as shown in Figure below.
A better way to write the max method is to use a generic type, as shown in the code below.
If you invoke the max method using
// 23 is autoboxed into new Integer(23)
MaxUsingGenericType.max("Welcome", 23);
a compile error will be displayed, because the two arguments of the max method in MaxUsingGenericType must have the same type (e.g., two strings or two integer objects). Furthermore, the type E must be a subtype of Comparable.
As another example, in the following code you can declare a raw type stack in line 1, assign new GenericStack to it in line 2, and push a string and an integer object to the stack in lines 3 and 4.
1 GenericStack stack;
2 stack = new GenericStack<String>();
3 stack.push("Welcome to Java");
4 stack.push(new Integer(2));
However, line 4 is unsafe because the stack is intended to store strings, but an Integer object is added into the stack. Line 3 should be okay, but the compiler will show warnings for both line 3 and line 4, because it cannot follow the semantic meaning of the program. All the compiler knows is that stack is a raw type, and performing certain operations is unsafe. Therefore, warnings are displayed to alert potential problems.