千家信息网

Java泛型中类型擦除问题怎么解决

发表于:2026-10-31 作者:千家信息网编辑
千家信息网最后更新 2026年10月31日,这篇"Java泛型中类型擦除问题怎么解决"文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇
千家信息网最后更新 2026年10月31日Java泛型中类型擦除问题怎么解决

这篇"Java泛型中类型擦除问题怎么解决"文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇"Java泛型中类型擦除问题怎么解决"文章吧。

假设有两个bean类

/** Test. */@Data@NoArgsConstructor@AllArgsConstructorpublic static class Foo {    public String name;} /** Test. */@Data@NoArgsConstructor@AllArgsConstructorpublic static class Dummy {    public String name;}

以及另一个对象

@NoArgsConstructor@AllArgsConstructor@Datapublic static class Spec {     public String spec;     public T deserializeTo() throws JsonProcessingException {        var mapper = new ObjectMapper();        return (T) mapper.readValue(spec, Foo.class);    }}

可以看到Spec对象中保存了以上两种类型json序列化后的字符串,并提供了方法将string spec 反序列化成相应的类型,比较理想的方式是在反序列化的方法中能够获取到参数类型 T 的实际类型,理论上运行时Spec类型是确定了,因此T也应该是确定的,但是因为类型擦除,所以实际上获取不到他的类型。

按照以下尝试 通过((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()获取泛型类型,经过测试是获取不到的

 @Test    public void test() throws JsonProcessingException {        var foo = new Foo("foo");        var spec = new Spec(mapper.writeValueAsString(foo));        var deserialized = spec.deserializeTo();        Assertions.assertTrue(deserialized instanceof Foo);    }     @NoArgsConstructor    @AllArgsConstructor    @Data    public static class Spec {         public String spec;         private Class getSpecClass() {            return (Class)                    ((ParameterizedType) getClass().getGenericSuperclass())                            .getActualTypeArguments()[0];        }         public T deserializeTo() throws JsonProcessingException {            var mapper = new ObjectMapper();            System.out.println(spec);            return (T) mapper.readValue(spec, getSpecClass());        }    }

会有以下的错误

java.lang.ClassCastException: class java.lang.Class cannot be cast to class java.lang.reflect.ParameterizedType (java.lang.Class and java.lang.reflect.ParameterizedType are in module java.base of loader 'bootstrap')

有两种办法来绕过这个问题

第一种比较简单,就是在创建spec对象时,直接把类型的class传进来,这样就可以直接使用。

第二种是创建spec的子类中使用这个方法就可以获取泛型的类型

@Datapublic abstract static class AbstractSpec {     public String spec;     public AbstractSpec(String spec) {        this.spec = spec;    }     private Class getSpecClass() {        return (Class)                ((ParameterizedType) getClass().getGenericSuperclass())                        .getActualTypeArguments()[0];    }     public T deserializeTo() throws JsonProcessingException {        var mapper = new ObjectMapper();        System.out.println(spec);        return (T) mapper.readValue(spec, getSpecClass());    }} public static class Spec extends AbstractSpec {    public Spec(String spec) {        super(spec);    }} @Testpublic void test() throws JsonProcessingException {    var foo = new Foo("foo");    var spec = new Spec(mapper.writeValueAsString(foo));    var deserialized = spec.deserializeTo();    Assertions.assertTrue(deserialized instanceof Foo);}

这里spec类就可以顺利的被反序列化。

这个和最开始失败的case的差别就是新增了一个子类,主要的差别是getGenericSuperclass的返回值有差异,非子类的情况下,获取到的是Object。

因此理论上子类Spec的类型信息中,实际上是保存了父类中的类型参数信息的,也就是例子中的Foo. 按照 https://stackoverflow.com/questions/42874197/getgenericsuperclass-in-java-how-does-it-work 的方式,可以查看到Spec类的字节码中有相应的类型信息。

$ javap -verbose ./org/apache/flink/kubernetes/operator/controller/GenericTest\$Spec.class | grep Signature  #15 = Utf8               Signature        Start  Length  Slot  Name   SignatureSignature: #19                          // Lorg/apache/flink/kubernetes/operator/controller/GenericTest$AbstractSpec;

以上就是关于"Java泛型中类型擦除问题怎么解决"这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注行业资讯频道。

类型 内容 问题 序列 信息 子类 实际 对象 就是 方法 参数 实际上 差别 文章 方式 理论 知识 篇文章 两个 也就是 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 百单网互联网科技有限公司怎么样 科技企业和互联网企业 智网互联网科技 深圳天众互联网科技公司 上海卓越科技 互联网 盛创互联网科技有限公司 联恩商钥互联网科技有限公司 恒生科技互联网指数分析 博兴的互联网电子科技公司 互联网大会黑科技排名 互联网科技公司有风险吗 成都互联网科技公司工作好不好 天津腾达互联网科技有限公司 互联网行业科技股 四川慕妮娅互联网科技有限公司 明优互联网科技有限公司 互联网科技公司营业执照怎么办理 信承诺互联网科技有限公司 安徽九吞吴互联网科技有限公司 瑞安市蟠桃会互联网科技有限公司 互联网通讯科技 互联网科技深圳 互联网科技开发公司 齐家互联网科技有限公司 左右互联网络科技 华服互联网科技官网 华夏恒生互联网科技013171 翼展科技 首家互联网医院 杭州披云加互联网科技有限公司 普陀区互联网教育科技管理办法
0