为什么型类型信息可以通过匿名内部类来保存

背景

Java的泛型是在编译阶段实现的,这意味着泛型类型信息在编译后的字节码中通常是不可用的,因为它们会被擦除(Type Erasure)。例如,List<String>List<Integer>在运行时都被视为简单的List

泛型类型的保留

然而,当你创建一个匿名内部类,并且这个匿名内部类继承自一个具体的泛型类型时,Java编译器会将这个具体的泛型类型作为匿名内部类的一部分类型信息保留下来。这是因为匿名内部类是一个特殊的类,它没有名称,但它扩展了一个父类或实现了一个接口,并且这个信息(包括泛型类型参数)是必须的,以便于编译器能够正确地生成字节码。

示例解释

假设我们有一个泛型接口Interface<T>:

java 复制代码
public interface Interface<T> {
    T performAction();
}

当我们创建一个匿名内部类并为其指定一个具体的泛型类型String时,如下:

java 复制代码
Interface<String> myInterface = new Interface<String>() {
    @Override
    public String performAction() {
        return "Action Performed";
    }
};

在上面的代码中,我们创建了一个实现了Interface<String>的匿名内部类。这里的关键点是,尽管泛型类型参数String通常会在运行时被擦除,但由于这是一个匿名内部类的创建,Java编译器实际上会将String类型参数作为这个匿名内部类的一部分保留下来。

如何获取这个类型信息

TypeToken类的作用就是利用这个特性来捕获这个保留下来的类型信息。当我们使用TypeToken时,我们实际上是在创建一个匿名子类,并让它继承自带有泛型类型参数的TypeToken类。这样,我们就可以通过反射来获取这个类型信息:

java 复制代码
TypeToken<Interface<String>> typeToken = new TypeToken<Interface<String>>() {};
Type type = typeToken.getType(); // 这个type可以用来获取完整的泛型类型信息

在上面的代码中,new TypeToken<Interface<String>>() {}创建了一个匿名子类,它继承自TypeToken并且指定了泛型参数为Interface<String>。通过调用getType()方法,我们可以获得这个泛型接口的完整类型信息,包括它的泛型类型参数String

这个Type对象可以用于反序列化操作,比如在Gson中,我们可以使用这个Type对象来告诉Gson如何正确地将JSON数据转换为特定的泛型类型的Java对象。

希望这个解释和示例能够帮助你更好地理解TypeToken的工作原理。

相关推荐
chuan.bai6 小时前
Java RAG 实战(第 8 篇):Spring Boot RAG 查询 API
java·spring boot·贪心算法
FlyWIHTSKY6 小时前
idea中集成claude功能
java·ide·人工智能·intellij-idea·cloudera
Java成神之路-6 小时前
Spring AI 统一结构化返回:ChatModel / ChatClient 两种实现方式
java·springaialibaba
Mr. zhihao6 小时前
深度解析:为什么Java序列化需要搭配ByteArrayOutputStream?IO装饰器模式的精妙设计
java·开发语言·装饰器模式
存在morning6 小时前
【Python 开发实践 一】Python vs Go vs Java 三门语言对比
java·python·golang
vx-程序开发6 小时前
springboot旅游推介平台---附源码24175
java·spring boot·python·spring cloud·eclipse·django·idea
艾莉丝努力练剑7 小时前
【QT:解决问题】Qt5Core.dll:无法定位程序输入点
java·开发语言·qt·学习·面试
小蒜学长7 小时前
“喵汪联盟”宠物领养系统的设计与实现(代码+数据库+LW)
java·spring boot·后端·宠物
程序员黑豆7 小时前
Java字符串常量池完全指南:原理、intern()方法与性能优化最佳实践
java·前端·ai编程
AI人工智能+电脑小能手7 小时前
大白话说Java设计模式-14-适配器模式(业务实战篇)
java·设计模式·适配器模式·系统兼容·多渠道对接