Detailed explanation
No. Java generics accept only reference types as type arguments, so List<int> and Map<int, String> do not compile. Use wrapper classes instead: List<Integer> or Map<Integer, String>. The same rule applies to other primitives: double becomes Double, boolean becomes Boolean, and so on. This restriction concerns type arguments, not the contents of a generic class: a generic class can still declare an ordinary int field. Also, List<int[]> is legal because an array is a reference type, even when its elements are primitives.
Java implements generics primarily through type erasure. The compiler checks type arguments and then translates type variables to their upper bounds, usually Object, inserting casts where necessary when values are retrieved. For example, retrieving an element from List<Integer> involves a runtime reference value that the compiler treats as Integer. A primitive int is not an Object and cannot directly substitute for that reference representation. Erasure also helped introduce generics while preserving compatibility with existing Java libraries and compiled code. In interviews, distinguish compile-time type checking from the erased representation used at runtime.
Autoboxing makes wrappers convenient but does not make primitive type arguments legal. With List<Integer> nums = new ArrayList<>(), nums.add(5) boxes the value through Integer.valueOf(5). Conversely, int first = nums.get(0) unboxes the retrieved Integer through intValue(). Unboxing null throws NullPointerException, which commonly happens when a Map<String, Integer> lookup finds no entry. Wrapper equality is another trap: == compares object identity, whereas equals() compares values for matching wrapper types. Integer.valueOf guarantees caching from -128 through 127; implementations may cache additional values, so == for boxed 128 values is not guaranteed to be false.
Boxing can add object allocation, reference storage, and garbage-collection overhead, although caching and JVM optimisations can avoid some allocations. For large numeric workloads, consider int[] or primitive-specialised APIs such as IntStream and OptionalInt; specialised collection libraries are another option. Interviewers generally expect the reference-type rule first, followed by a small boxing example and awareness of null, equality, and performance pitfalls.
Key points to remember
- Primitive type arguments such as List<int> are illegal; use List<Integer>.
- Erasure replaces type variables with Object or their upper bound.
- Autoboxing and unboxing bridge primitives and wrappers, not generic type arguments.
- Unboxing null throws NullPointerException; use equals() for wrapper value comparisons.
- List<int[]> is legal, and primitive arrays avoid per-element boxing.
Common mistakes candidates make
- Assuming autoboxing makes List<int> valid syntax.
- Using == for wrapper values or claiming boxed 128 values must always have different identities.
- Ignoring null when unboxing a map lookup or assuming boxing always creates a new object.
Likely follow-up questions
Why does Java use type erasure?
Erasure allowed generics to be introduced while maintaining compatibility with existing libraries and compiled code. It provides compile-time type checking without creating a separate runtime class for every parameterised type.
Why is List<int[]> allowed when List<int> is not?
An int[] is an object and therefore a reference type, so it is a valid generic type argument. Each list element references an entire primitive array, rather than directly storing a primitive int.
Could Java support primitive type arguments in the future?
Project Valhalla is exploring value objects and generics specialisation, with the broader goal of reducing the gap between primitive and reference-based programming. Do not present List<int> as currently supported Java syntax or promise a particular release timeline.
Interview tip: Start with “No, use wrapper types,” demonstrate List<Integer> with boxing and unboxing, and then mention erasure and one practical pitfall.
