Java generics and class literals
How to use Mockito's ArgumentCaptor with parameterized generic types like List<Long> using a double cast to work around Java's type erasure.
When using Mockito's ArgumentCaptor with a parameterized type like List<Long>, you run into a fundamental Java limitation: class literals for generic types don't exist (e.g., List<Long>.class is not valid syntax).
The Problem
The intuitive casting approach fails at compile time:
ArgumentCaptor<List<Long>> captor =
(ArgumentCaptor<List<Long>>) ArgumentCaptor.forClass(List.class);
// Error: "Cannot cast from ArgumentCaptor<List> to ArgumentCaptor<List<Long>>"The Solution
The working solution uses a double cast to bypass type safety restrictions:
ArgumentCaptor<List<Long>> captor =
ArgumentCaptor.forClass((Class<List<Long>>)(Class) List.class);This generates an unchecked type-safety warning but compiles and works correctly. The double cast first erases the raw type to Class, then casts it to Class<List<Long>>, which the compiler allows.
Alternative: @Captor Annotation
If you are using Mockito's annotation runner, the @Captor annotation avoids the casting entirely:
@Captor
private ArgumentCaptor<List<Long>> captor;This approach is cleaner and avoids the type-safety warning, making it the preferred solution when using MockitoJUnitRunner or MockitoAnnotations.initMocks(this).