为什么 Jackson TypeReference 是抽象的?

Che*_*ian -1 java jackson

为什么 Jackson 的 TypeReference 是抽象的?它通常会使用法变得更丑陋,因为您需要包含大括号来创建内联类(并且大多数 linter 强制您在同一行上没有大括号)。

https://github.com/FasterXML/jackson-core/blob/master/src/main/java/com/fasterxml/jackson/core/type/TypeReference.java

new TypeReference<Map<String, String>>() {
};
Run Code Online (Sandbox Code Playgroud)

这是由于一些晦涩的 Java 语言限制吗?

JB *_*zet 7

正是为了强制您创建子类,因为这是捕获泛型类型的唯一方法。

它写在您链接到的 javadoc 的第一句话中:

该泛型抽象类用于通过子类化来获取完整的泛型类型信息。

(强调我的)。

该文档还提供了解释该原理的博客文章的链接。


And*_*ner 6

JB Nizet 已经回答了原因。我只是想展示行动的原则。

您可以在其他课程上亲自尝试:

List<String> a = new ArrayList<String>();
List<String> b = new ArrayList<String>() {};

System.out.println(a.getClass().getGenericSuperclass());
System.out.println(b.getClass().getGenericSuperclass());
Run Code Online (Sandbox Code Playgroud)

Ideone demo

输出:

java.util.AbstractList<E> 
java.util.ArrayList<java.lang.String>
Run Code Online (Sandbox Code Playgroud)

如您所见,创建匿名子类会在运行时保留有关列表的具体泛型类型的类型信息。

A 的TypeReference作用大致相同:

new TypeReference<Map<String, String>>() { }
Run Code Online (Sandbox Code Playgroud)

有一个通用的超类:

 TypeReference<java.util.Map<java.lang.String, java.lang.String>>
Run Code Online (Sandbox Code Playgroud)

从这里,你可以得到类型Map<String, String>。如果您为另一种类型创建了类型引用:

    new TypeReference<Map<Integer, Integer>>() { };
Run Code Online (Sandbox Code Playgroud)

你可以得到类型Map<Integer, Integer>>,它与Map<String, String>.

如果TypeReference不是抽象的,你可以写:

TypeReference<Map<String, String>> p = new TypeReference<>();
TypeReference<Map<Integer, Integer>> q = new TypeReference<>();
Run Code Online (Sandbox Code Playgroud)

但种类p和q会难以区分。