Java - 用于存储函数的Typesafe异构容器模式

时间:2017-04-19 00:37:02

标签: java generics

这是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问题中描述的模式,但我在最后一行遇到问题,我试图为apply方法调用存储在Function中的Map方法{1}}。

我收到的错误消息是

The method apply(capture#6-of ?) in the type Function<capture#6-of ?,JSONObject> is not applicable for the arguments (capture#7-of ?)

我能做些什么来解决这个问题,还是有其他结构可以用来达到同样的目标?

1 个答案:

答案 0 :(得分:0)

让编译器知道klass是代表Class的{​​{1}} - s类型,这是一种魔力:

object

第一个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运行时类型令牌是属于实际对象的令牌。