Jackson可序列化泛型类却无法反序列化,如何解决?
解决Jackson反序列化泛型类B的问题
首先,你的报错Cannot deserialize EmbeddedTest$1B (of type local/anonymous) as a Bean已经给出了关键线索——Jackson误把你匿名内部类形式的TypeReference关联的泛型类当成了匿名内部类的子类,再加上Lombok的@Data注解在处理泛型+匿名类场景时的潜在兼容性问题,就导致了反序列化失败。
下面给你几个可行的解决方案:
方案1:用TypeFactory构造泛型类型(最稳妥)
避免使用匿名内部类的TypeReference,直接通过Jackson的TypeFactory来构造泛型类型,这样能明确告诉Jackson要反序列化的是B<A>这个具体泛型类:
@Data class A { String b; } @Data @NoArgsConstructor // 显式添加无参构造,确保Jackson能实例化 class B<T> { T c; } public static void main(String[] args) throws JsonProcessingException { A a1 = new A(); a1.setB("sa"); B<A> s = new B<>(); s.setC(a1); ObjectMapper objectMapper = new ObjectMapper(); String sj = objectMapper.writeValueAsString(s); System.out.println(sj); // {"c":{"b":"sa"}} // 用TypeFactory构造泛型类型 Type targetType = TypeFactory.defaultInstance().constructParametricType(B.class, A.class); B<A> ba = objectMapper.readValue(sj, targetType); System.out.println(ba.getC().getB()); // 输出sa,反序列化成功 }
方案2:修正TypeReference的使用方式
如果你坚持用TypeReference,可以避免匿名内部类的写法,或者显式指定类型:
// 方式一:创建静态内部类形式的TypeReference,而非匿名类 static class BTypeReference extends TypeReference<B<A>> {} // 反序列化时使用 B<A> ba = objectMapper.readerFor(new BTypeReference()).readValue(sj); // 方式二:结合readerFor和withType B<A> ba = objectMapper.readerFor(B.class) .withType(new TypeReference<B<A>>() {}) .readValue(sj);
方案3:确保Lombok生成正确的类结构
虽然@Data默认会生成无参构造、getter/setter,但在泛型场景下,显式添加@NoArgsConstructor和@Getter/@Setter(或者保留@Data+显式无参构造)能避免潜在的实例化问题:
@Data @NoArgsConstructor class B<T> { T c; }
为什么匿名内部类会导致问题?
当你写new TypeReference<B<A>>() {}时,Java会生成一个匿名内部类(类名类似YourMainClass$1),Jackson在解析这个类型时,会错误地认为要反序列化的是这个匿名类的子类,而不是原本的B<T>。而Jackson默认不会将匿名/local类当作可序列化的Bean,因此抛出了那个错误。
内容的提问来源于stack exchange,提问作者osese
相关产品推荐
相关产品推荐

