· · ─ ·✶· ─ · ·
So recently I was writing a junit and ended up needing to use reflection to get access to a private class method to test it.
Method method = MergeSort.class.getDeclaredMethod(
"merge",
List.class,
List.class
);
method.setAccessible(true);
List<Integer> mergedActual = (List<Integer>) method.invoke(mergeSort, left, right);Intellij immediately gave me a warning - Unchecked cast: 'java.lang.Object' to 'java.util.List<java.lang.Integer>'
I understand that this is because invoke() gives back Object and and at compile time, the compiler has no idea if my method actually returns List<Integer> or not.
Now combine that with type erasure, which is something that happens at runtime.
At runtime, Java does not really know the generic parameter (Integer) anymore. A List<Integer> and List<String> are both just List at runtime. So the JVM can only verify:
Object -> Listbut cannot verify:
Object -> List<Integer>NOTE: The warning represents a concern at both, compile-time and runtime.
How to fix this?
- Suppress the warning if we know what we’re doing
@SuppressWarnings("unchecked")
List<Integer> mergedActual =
(List<Integer>) method.invoke(mergeSort, left, right);- We could cast to
List<?>
List<?> mergedActual =
(List<?>) method.invoke(mergeSort, left, right);· · ─ ·✶· ─ · ·