首页 > 解决方案 > 防止构造“原始类型”引用

问题描述

Jackson Core 库包含TypeReference抽象类。

该类实现Comparable. JavaDoc解释了原因:

它使用一个...

... Comparable 的虚假实现(任何这样的泛型接口都可以,只要它强制实现具有泛型类型的方法),以确保确实给出了 Type 参数。

和:

compareTo():我们定义此方法(并要求实现 Comparable)的唯一原因是防止在没有类型信息的情况下构造引用。

TypeReference 使用类型信息 ( Map<String, Object>)的示例:

String json = "{ \"some_key\": 123 }";
ObjectMapper objectMapper = new ObjectMapper();
TypeReference<Map<String, Integer>> typeReference = new TypeReference<>(){};
Map<String, Integer> map = objectMapper.readValue(json, typeReference);

(该类是抽象的,但它包含compareTo()- 所以我不需要提供一个实现。)

上述技术并没有阻止我构建没有类型信息的引用。以下编译成功(尽管最终结果没有用):

// bad idea - just for illustration:
TypeReference typeReference2 = new TypeReference() {};

我对Comparable这里的使用缺少什么?它不会阻止代码编译。我不明白它怎么可能。

编译器警告是另一回事 - 我特别想知道“预防”声明。


背景说明

如果我尝试使用我的原始类型typeReference2,它将引发运行时异常,因为在构造函数中进行了以下检查

Type superClass = getClass().getGenericSuperclass();
if (superClass instanceof Class<?>) { // sanity check, should never happen
    throw new IllegalArgumentException("Internal error: TypeReference constructed without actual type information");
}

该类的 Javadoc 参考了一篇讨论上述运行时技术的文章。似乎那篇文章中的一条评论促使将其纳入Comparable杰克逊的TypeReference课堂:

与其在构造函​​数中检查类型参数,不如将其设为语法错误以省略:

public abstract TypeReference<R> implements Comparable<TypeReference<R>> {
    // ...
    public int compareTo(TypeReference<R> o) {
        // Need a real implementation.
        // Only saying "return 0" for illustration.
        return 0;
    }
}

现在这是合法的:

new TypeReference<Object>() { };

但这是未实现 Comparable 的语法错误:

new TypeReference() { };

我不认为这是TypeReference. 它可以编译,并且我们已经在类中获得了一个实现

标签: javagenerics

解决方案


推荐阅读