Sunday, May 13, 2012

JDK7: Using the diamond operator for constructor type inference

The use of the diamond operator simplifies the use of generics when creating an object. It avoids unchecked warnings in a program, and it reduces generic verbosity by not requiring explicit duplicate specification of parameter types. Instead, the compiler infers the type.

Dynamically-typed languages do this all the time. While Java is statically typed, the use of the diamond operator allows more inferences than before. There is no difference in the resulting compiled code.

The compiler will infer the parameter types for the constructors. This is an example of the convention over configuration. By letting the compiler infer the parameter type (convention), we avoid explicit specification (configuration) of the object. Java also uses annotations in many areas to affect this approach. Type inference is now available, whereas it was only available for methods before.

Getting ready…
To use the diamond operator:
  1. Create a generic declaration of an object.
  2. Use the diamond operator, <>, to specify the type inference that is to be used.
How to do it...
  1. Create a simple Java application with a main method. Add the following code example to the main method to see how they work. For example, to declare a java.util.List of strings, we can use the following:
  2. The identifier, list, is declared as a list of strings. The diamond operator, <>, is used to infer the List type as String. No warnings are generated for this code.
How it works…

When an object is created without specifying the data type, it is called a raw type. For example, the following uses a raw type when instantiating the identifier, list:

When the code is compiled, the following warnings are generated:

Note: packt\Bin.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.

An unchecked warning is generated. It is generally desirable to eliminate unchecked warnings in an application. When the –Xlint:unchecked is used we get the following:

Before Java 7, we could address this warning by explicitly using a parameter type as follows:

With Java 7, the diamond operator makes this shorter and simpler. This operator becomes even more useful with more complex data types, such as, a List of Map objects as follows:

There's more...

There are several other aspects of type inference that should be discussed:
  1. Using the diamond operator when the type is not obvious.
  2. Suppressing unchecked warnings.

1- Using the diamond operator when the type is not obvious

Type inference is supported in Java 7 and later, only if the parameter type for the constructor is obvious. For example, if we use the diamond operator without specifying a type for the identifier shown as follows, we will get a series of warnings:

Compiling the program with –Xlint:unchecked, results in the following warnings:

These warnings will go away if the data type is specified as follows:

2- Suppressing unchecked warnings
While not necessarily desirable, it is possible to use the @SuppressWarnings annotation to suppress unchecked exceptions generated by the failure to use the diamond operator. The following is an example of this: