The problem is that the following code can't compile if the generic signature consists of several ?
which are the same type.
import java.util.Map;
import java.util.HashMap;
import java.util.function.Function;
public class Test {
private static <T> T findSelfReference(Map<T, T> map) {
for (Map.Entry<T, T> entry : map.entrySet()) {
if (entry.getKey() == entry.getValue()) {
return entry.getKey();
}
}
return null;
}
private static <T> T findSelfReference2(Map<T, T> map) {
for (T key : map.keySet()) {
if (map.get(key) == key) {
return key;
}
}
return null;
}
// Question: How to write the method signature that can ensure compile-time type safety? Both the signatures fail to compile.
// private static <T> String fun(Function<Map<T, T>, T> finder) {
private static String fun(Function<Map<?, ?>, ?> finder) {
Map<Integer, Integer> map1 = new HashMap<>();
// some processing to map1
Integer n = finder.apply(map1); // usage here, compile-time type checking wanted
Map<String, String> map2 = new HashMap<>();
// other processing to map2 depending on n
return finder.apply(finder, map2); // another usage
}
public static void main(String[] args) {
// Please don't change into helper class...
System.out.println(fun(Test::findSelfReference));
System.out.println(fun(Test::findSelfReference2));
}
}
In fun
, inside each call to finder.apply()
the type T
is fixed. But among different calls they use different types. I tried the wildcard capture (ref: here) but no luck.
I don't want to cast the result into Object in which the checking has to be made in runtime. All type checking should be done in compile time.
Is it possible without making O(n) helper classes where n is the number of inline function?
The problem is that you want the finder
's apply
method to be generic.
The solution is to define your own functional interface with a generic method.
@FunctionalInterface
interface Finder {
<T> T apply(Map<T, T> map);
}
private static String fun(Finder finder) {
// same body
}
If this counts as a "helper class" then I don't know what to tell you. You are trying to pound a square peg in to a round hole. Function#apply
isn't a generic method so you can't do this with Function
.