Type Inference in Java
Local Variables
Type inference is where the compiler will infer the data type of a variable. This allows you to skip writing the data type. Java 10 introduces the ability to use type inference on local variables that are not null. Type inference is only supported on local variables.
The following code shows explicitly specifying the data type on a variable.
final String greeting = "Hello";
You can have the compiler infer the data type instead with the following:
final var greeting = "Hello";
When using type inference, you must assign a value to a variable when it is declared. If you do not, there isn't a way for the compiler to infer the data type, and it will result in a compiler error.
// Compiler error:
// cannot infer type for local variable greeting
final var greeting;
greeting = "Hello!";
The var Identifier
Var may look like a keyword, but it is actually a new identifier. It is implemented this way so any existing variables, methods, and packages that use the name var won't be affected. Because of this, you can actually write the following:
final var var = 10;
When Should Type Inference Be Used?
The goal of adding type inference to Java is for code readability. Because of this, the number one thing to consider with type inference is the following:
"Reading code is more important than writing code."
Local Variable Type Inference Style Guidelines
Your code readability should be independent of your IDE (Integrated Development Environment). If you are using type inference and require your IDE due to code readability, don't use type inference.
Only use type inference when you gain readability. Readability can both be gained by explicitly defining a data type or inferring the data type depending on the code.
Redundant Information
One obvious place to use type inference is when you have redundant information.
final User user = new User();
This would be better using type inference to eliminate the redundant information.
final var user = new User();
Method Return Values
When you are dealing with a return value from a method call, it is important to have good variable names when using type inference.
final var inputStream = socket.getInputStream()
Even with good variable names, type inference may not be what you want to use if it effects code readability.
final var message = create();
What data type is message? Is it a String, a Message object, or something else? If you find yourself in a scenario where you have this confusion, type inference should be avoided.
Programming to an Interface
Local variables should be minimized in scope. Because of this, programming to an interface is less of a concern. Instead of writing the following:
final List<String> items = new ArrayList<>();
You can use the following even though the compiler will infer the data type as an ArrayList.
final var items = new ArrayList<String>();
If you are minimizing the scope of local variables, this shouldn't be a problem.
Conclusion
Type inference is done using the var identifier and can only be used on local variables. When using type inference, you must assign a value when the variable is declared. Be mindful of code readability when using type inference and only use it when it makes the code more readable.