Java - 用于存储函数的类型安全异构容器模式

标签 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问题中描述的模式,但我在最后一行遇到了一个问题,我试图为存储在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/

相关文章:

.net - 插入到通用字典中可能存在重复键吗?

ios - 泛型参数受其他泛型参数约束

java - 使用泛型的工厂对象创建者

java - Scala、Elasticsearch 新的 RestHighLevelClient 和 BulkProcessor

java 使用不同的 JDK 版本构建 : same artifacts?

java - 如何从 Java 代码将包含 ESC/POS 命令的 .text 文件发送到打印机

java - 无法使用通配符泛型类型向 Java 集合添加值

java - 如何从gitlab中删除文件夹

Java:ArrayList 说索引 0 不存在,除非我在父循环中包含字符串

Java - 是否存在协变和逆变?