The correct steps to get rid of the warning is:
- First and foremost, prove that the unchecked cast is safe, and document why
- Only then perform the unchecked cast, and annotate
@SuppressWarnings("unchecked")
on the variable declaration (not on the whole method)
So something like this:
// this cast is correct because...
@SuppressWarnings("unchecked")
GenericInterface<String> mockedInterface =
(GenericInterface<String>) EasyMock.createMock(GenericInterface.class);
Guidelines
The following is excerpt from Effective Java 2nd Edition: Item 24: Eliminate unchecked warnings:
- Eliminate every unchecked warning that you can.
- If you can't eliminate a warning, and you can prove that the code that provoked the warning is typesafe, then (and only then) suppress the warning with
@SuppressWarning("unchecked")
annotation.
- Always use the
SuppressWarning
annotation on the smallest scope possible.
- Every time you use an
@SuppressWarning("unchecked")
annotation, add a comment saying why it's safe to do so.
Related questions
Refactoring the cast
It is also possible in most cases to perform the unchecked cast inside a generified createMock
. It looks something like this:
static <E> Set<E> newSet(Class<? extends Set> klazz) {
try {
// cast is safe because newly instantiated set is empty
@SuppressWarnings("unchecked")
Set<E> set = (Set<E>) klazz.newInstance();
return set;
} catch (InstantiationException e) {
throw new IllegalArgumentException(e);
} catch (IllegalAccessException e) {
throw new IllegalArgumentException(e);
}
}
Then elsewhere you can simply do:
// compiles fine with no unchecked cast warnings!
Set<String> names = newSet(HashSet.class);
Set<Integer> nums = newSet(TreeSet.class);
See also