这是 Java map with values limited by key's type parameter 的扩展。但是,我尝试使用 Map
来存储 Function
。
private static Map<Class<?>, Function<?, JSONObject>> serializers = new HashMap<>();
private static <T> void addSerializer(Class<T> klass, Function<T, JSONObject> fn) {
serializers.put(klass, fn);
}
private static <T> Function<T, JSONObject> getSerializer(Class<T> klass) {
return (Function<T, JSONObject>) serializers.get(klass);
}
static {
// add entries with addSerializer
}
public static JSONObject serialize(Object object) {
Class<?> klass = object.getClass();
return serializers.get(klass).apply(klass.cast(object));
}
我遵循了链接的SO问题中描述的模式,但我在最后一行遇到了一个问题,我试图为存储在Map
中的Function
调用apply
方法。
我收到的错误消息是
The method apply(capture#6-of ?) in the type Function<capture#6-of ?,JSONObject> is not applicable for the arguments (capture#7-of ?)
我可以做些什么来解决这个问题,或者我可以使用其他结构来实现相同的目标吗?
最佳答案
这里有一些魔法可以让编译器知道klass
是代表object
-s类型的Class
:
public static JSONObject serialize(Object object) {
Class cls = object.getClass();
return serialize(cls, cls.cast(object));
}
private static <T> JSONObject serialize(Class<T> klass, T object) {
return getSerializer(klass).apply(object);
}
第一个 serialize
方法检索类(或抛出 NullPointerException
),然后将对象转换为其自己的类型,然后调用第二个 serialize
方法。现在,第二个 serialize
方法有自己的类型参数 T
,因此它可以安全地调用 Function.apply
。
不幸的是,我们需要这种间接方式来让编译器知道 klass
运行时类型标记是属于实际对象的标记。
关于Java - 用于存储函数的类型安全异构容器模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43484351/