Interview Prep Zoneby CuriouserLabs

Question 5 of 5 · senior level

How does type inference work (diamond, var, generic methods)? Where does it bite back?

🎤 Say this first

The compiler infers type arguments from context: generic-method invocation infers from arguments and the target type (since Java 8, poly expressions), the diamond <> infers constructor type arguments, and var (Java 10) infers local variable types from initializers — it is not dynamic typing, everything stays statically typed. Bite-backs: var with diamond infers Object parameters, inferred types can be over-precise (anonymous/intersection types), and readability suffers when the right-hand side doesn't reveal the type.

The full picture

Inference wins and losses
var names = new ArrayList<String>();    // ✅ ArrayList<String>
var oops  = new ArrayList<>();           // ⚠️ ArrayList<Object> — diamond + var
var entry = Map.entry("a", 1);           // Map.Entry<String,Integer> — nice
var list  = List.of(1, 2.0);             // List<? extends Number&Comparable…> 😱

// Target typing: the SAME expression, two types
Comparator<String> byLen = Comparator.comparing(String::length);
Function<String,Integer> f = String::length;  // context decides

// Conditional operator surprise:
Object o = flag ? 1 : "x";  // infers Object&Serializable&Comparable… fine
long ms = flag ? 1 : longValue;  // numeric promotion — subtle bugs
  • Team rule of thumb for var: allowed when the type is obvious from the right side (constructors, factories, casts); avoided for method-call chains returning non-obvious types and in public-facing signatures (where it's illegal anyway).
  • Generic method inference failure mode: when inference picks a common supertype you didn't want, add an explicit witness — Collections.<Runnable>emptyList().
  • var in lambda parameters (Java 11) exists mainly to hang annotations on: (@Nonnull var x) -> ….

🔄 Likely follow-up questions

  • What is a poly expression and how did Java 8 change inference?
  • Why can't fields or method returns use var?
  • How do you force a specific type argument when inference fails?