java 使用TypeReference而不使用具体类的ObjectMapper反序列化

flseospp  于 2023-01-29  发布在  Java
关注(0)|答案(1)|浏览(220)

我遇到了下面的源代码,我不明白:

final Book book = objectMapper.readValue(string, new TypeReference<>() {
    });

Jackson如何理解从提供的字符串反序列化哪个类?
我在this article中发现了一个类似的构造,它被写为抛出一个异常。但是代码实际上工作了,Book被反序列化了。这是什么黑魔法?

zmeyuzjn

zmeyuzjn1#

这是处理Java泛型类型擦除的一种聪明方法。
为了实现泛型,Java编译器将类型擦除应用于:

  • 将泛型类型中的所有类型参数替换为它们的bounds或Object(如果类型参数未绑定)。因此,生成的字节码仅包含普通类、接口和方法。
  • 必要时插入类型转换以保持类型安全。
  • 生成桥方法以保留扩展泛型类型中的多态性。

Neil Gafter指的是

public abstract class TypeReference<T> {}

作为 * 超类型令牌 *。
当您现在执行

TypeReference<Book> x = new TypeReference<Book>() {};

或在Neals example

TypeReference<List<String>> x = new TypeReference<List<String>>() {};

在赋值语句右边创建的匿名类不会发生类型擦除,它有一个固定的泛型类型,可以被超类访问,如下所示:

protected TypeReference() {
        Type superclass = getClass().getGenericSuperclass();
        if (superclass instanceof Class) {
            throw new RuntimeException("Missing type parameter.");
        }
        this.type = ((ParameterizedType) superclass).getActualTypeArguments()[0];
    }

Jacksons ObjectMapper稍后将使用this.type来确定您想要反序列化的内容的类型。
菱形操作员的观察通常是正确的。

相关问题