Raw Types and Backward Compatibility

paulike

Paul Ngugi

Posted on July 4, 2024

Raw Types and Backward Compatibility

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:

Image description

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.

Image description

A better way to write the max method is to use a generic type, as shown in the code below.

Image description

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.

💖 💪 🙅 🚩
paulike
Paul Ngugi

Posted on July 4, 2024

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related