How does type inference work?

First, let's clarify what type inference is. Type inference refers to the compiler's ability to deduce the type of an expression without explicit type annotations from the programmer. In most interview settings, you won’t be asked about the technical details of the type inference algorithm itself. It’s more about understanding that type inference happens statically, based on the argument types and expected return type. Essentially, the real question is “what is type inference, and when does it occur?”

When people think of "type inference" in Java, the first thing that often comes to mind is the diamond operator <>. Introduced in Java 7, the diamond operator is used with generic class constructors, allowing the compiler to infer the type instead of requiring you to declare it explicitly, helping to avoid raw types.

In Java 9, the diamond operator was extended to work with anonymous classes.

For generic methods, specifying the type parameter explicitly is possible, but the diamond operator is syntactically invalid here - since type inference is automatic by default.

In Java 10, the var keyword was introduced for local variable type inference. It works similarly to other modern programming languages - var is used in place of a specific type during declaration, and the compiler infers the type based on the assigned value.

When working with lambda expressions, the parameter types can also be omitted because the compiler can infer them. Starting with Java 11, you can use var in lambda parameters to specify that the type should be inferred while also allowing the application of annotations or modifiers to the parameters.
How does type inference work?