防止构建“原始类型”引用

时间:2021-01-28 20:34:24

标签: java generics

Jackson Core 库包含 TypeReference 抽象类。

这个类实现了ComparableJavaDoc 解释了原因:

它使用...

<块引用>

... 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,它会抛出一个运行时异常,因为以下check in the constructor

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 引用了讨论上述运行时技术的 an article。似乎那篇文章中的一条评论促使在 Jackson 的 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 的语法错误。编译正常,we've been given an implementation in the class already

0 个答案:

没有答案