I wish to implement a method with the following signature:
<T> void function(Class<T> clazz, Consumer<T> consumer)
This function takes an Object obj (supplied elsewhere), uses clazz.cast(obj) to cast it to T, and then invokes consumer with it. (Basically, it is a guard for consumer.)
This works more or less fine, I can write
Consumer<String> c = ...;
function(String.class, c);
Unfortunately, the following code does not work:
Consumer<List<String>> c = ...;
function(List.class, c);
This is because List.class has type Class<List>, not class Class<List<String>>.
I can change the type of c to Consumer<List>, but that would be incompatible with my code in other places (and raw types are not nice anyway).
Is there some way to (a) invoke function in a way that typechecks or (b) change the type signature of function in a way that makes this pattern work?
Notes:
I wish to retain as much compile and runtime type safety as possible. So,
function(Class<?> clazz, Consumer<T> consumer)would not be acceptable because the user can easily provide the wrongclazz. And invoking asfunction((Class<List<String>>)List.class, c)is also not acceptable because I could accidentally cast it asfunction((Class<Integer>)List.class, c)and this wrong cast would not even be caught at runtime. If there was a function that allows to castClass<C<T>>toClass<C<U>>but not toClass<D>, that would be cool, but I don't see that without higher-order types.I am aware that the type casts will not be able to check at runtime that we have a
List<String>and not aList<Integer>. That's OK. (Well, it's not, but I assume it's the best we can expect in a JVM language.)All being the same, I prefer solutions that make the invocation of
functionsimple (possible makingfunctionmore complex) becausefunctionis defined in my library and used by the user of that library.For the curious, the actual code where I have this problem is here,
Instanceisfunction.