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

背景

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的工作原理。

相关推荐
狼爷8 小时前
吃透 Java Function 接口,搞定 99% 的 Stream 场景
java·函数式编程
祎雪双十Gy12 小时前
从 DataX 的配置加载说起:我用 FastJson2 做了一个轻量级动态配置管理库
java·后端
小锋java123412 小时前
分享一套锋哥原创的SpringBoot4+Vue3宠物领养网站系统
java
考虑考虑15 小时前
Java实现hmacsha1加密算法
java·后端·java ee
掉鱼的猫16 小时前
Spring Boot → Solon 注解迁移实战指南:一张对照表说清楚
java·spring boot
plainGeekDev16 小时前
广播接收器 → Flow + Lifecycle
android·java·kotlin
plainGeekDev16 小时前
EventBus → SharedFlow
android·java·kotlin
带刺的坐椅17 小时前
Spring Boot → Solon 注解迁移实战指南:一张对照表说清楚
java·springboot·web·solon
用户37215742613517 小时前
Java 将一个 PPT 文档拆分为多个文件
java
人活一口气1 天前
Spring Boot与AIGC的完美结合:从零搭建智能内容生成平台
java·spring boot·aigc