Let's assume the following method (say from Guava's Iterables):
public static <T> Iterable<T> filter(final Iterable<?> unfiltered, final Class<T> type) {
return null;
}
and this collection:
Set<?> objs = ...;
then the following code compiles and the generics are correctly derived
Iterable<String> a2 = Iterables.filter(objs, String.class);
(In Guava this would return an iterable of all Strings in objs
.)
But now lets assume the following class:
static class Abc<E> {
E someField;
}
I have no idea how to call filter
and get Iterable<Abc<?>>
:
Iterable<Abc> a3 = Iterables.filter(objs, Abc.class);
Iterable<Abc<?>> a4 = Iterables.filter(objs, Abc.class); // Compile error - Abc and Abc<?> are incompatible types
Iterable<Abc<?>> a5 = Iterables.filter(objs, Abc<?>.class); // Compile error
Iterable<Abc<?>> a6 = Iterables.<Abc<?>>filter(objs, Abc.class); // Compile error
Iterable<Abc<?>> a7 = (Iterable<Abc<?>>) Iterables.filter(objs, Abc.class); // Compile error - inconvertible types
Iterable<Abc<?>> a8 = Iterables.filter(objs, new Abc<?>().getClass()); // Compile error
Iterable<Abc<?>> a8a = Iterables.filter(objs, new Abc<Object>().getClass()); // Compile error
Only a3 compiles, but then I do not have the parameter on Abc, and thus no generic type checking in subsequent code is done.
I know that the type parameters are not present at runtime and so I do not atempt to write code like:
Iterable<Abc<String>> a9 = Iterables.filter(objs, Abc<String>.class); // Compile error
I just want to filter all objects of the type Abc (as a3 does) but having the generic parameter in the result. The only way of doing this I found is the following, which is silly:
Iterable<Abc<?>> a10 = new HashSet<Abc<?>>();
for (Abc<?> a : Iterables.filter(objs, Abc.class)) {
((Set<Abc<?>>)a10).add(a);
}
Thanks.