Java / Java 21 Interview Questions
How does type erasure affect instanceof checks with generics in Java?
Type erasure means generic type parameters are removed at compile time, leaving only the raw type at runtime. This has direct implications for instanceof checks.
// Cannot check parameterised generic types at runtime
List<String> strings = List.of("a", "b");
if (strings instanceof List<String>) { } // compile error - cannot check List <String>
if (strings instanceof List<?>) { } // OK - wildcard is fine
if (strings instanceof List) { } // OK - raw type is fine (with warning)
// Generic type parameter in pattern ÂÂ unchecked warning
// The JVM can only check 'instanceof List', not 'instanceof List'
// Java 21 allows wildcard in pattern
static void process(Object obj) {
if (obj instanceof List<?> list) {
list.forEach(System.out::println); // OK ÂÂ each element is Object
}
}
// Workaround: check elements individually
static boolean isListOfStrings(Object obj) {
if (obj instanceof List<?> list) {
return list.stream().allMatch(e -> e instanceof String);
}
return false;
}
// getClass() also suffers from erasure
List<String> ls = new ArrayList<>();
List<Integer> li = new ArrayList<>();
System.out.println(ls.getClass() == li.getClass()); // true ÂÂ both ArrayList
Type erasure is the root cause. Java generics are a compile-time mechanism; at runtime both List<String> and List<Integer> are simply List. Pattern matching cannot change this ÂÂ instanceof List<String> would require the JVM to inspect every element, which is why it is disallowed. Project Valhalla (future Java) aims to address this with reified generics via value types.
More Related questions...