为什么Gson中的TypeToken结构如此奇怪?

Jud*_*ing 14 java json constructor gson

当我使用Gson在object和json之间进行解析时,TypeToken的初始化是如此奇怪:

Type collectionType = new TypeToken<Collection<Integer>>(){}.getType();
Run Code Online (Sandbox Code Playgroud)

我只知道这种格式:new TypeToken<Collection<Integer>>().getType();上面的括号是什么?提前致谢!

PS我已经查看了TypeToken类的源代码,它是一个class(不是接口或抽象),没有任何构造函数,这意味着它使用no-parameter constructor默认值.

PS2当我删除大括号时,它告诉我构造函数不可见.当我查看TypeToken类时,这是构造函数:

  protected TypeToken() {
        this.type = getSuperclassTypeParameter(getClass());
        this.rawType = (Class<? super T>) $Gson$Types.getRawType(type);
        this.hashCode = type.hashCode();
  }
Run Code Online (Sandbox Code Playgroud)

为什么不用它public呢?

Per*_*ion 18

"怪异"并不是一个技术术语.该类的定义方式是强制您显式指定与其具体实例关联的泛型参数.因为已编译的Java类保留有关其通用参数的信息,所以信息随后可供需要它的框架库使用.

这就是超级型令牌的目的.

  • 嗯,实际上,保护构造函数是必不可少的.它阻止人们能够做到`TypeToken <Whatever> t = new TypeToken <Whatever>();`,这会破坏班级的整个目的.事实上,你被迫*实际上是子类,以便完全定义令牌,这是设计者的意图.你可以把整个事情想象成一个黑客来解决Java通过类型擦除实现泛型的事实.希望能让事情变得更加清晰. (4认同)

Bhe*_*ung 7

new TypeToken<Collection<Integer>>(){}意味着您正在创建一个扩展的匿名内部类TypeToken<Collection<Integer>>.同时,您正在创建该匿名类的实例.

从链接:

匿名类使您可以使代码更简洁.它们使您能够同时声明和实例化一个类.他们就像当地的班级,除了他们没有名字.如果您只需要使用本地类一次,请使用它们.