泛型类的.class问题,请高手帮忙修改代码!

时间:2021-04-27 19:20:50

public static <T> T ReadJson(String _strJson, Class<T> _class)
{
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

T t = null;
try {
t = objectMapper.readValue(_strJson, _class);    // (1)这个地方需要依靠_class来进行Json语句的值解析
} catch (JsonParseException e) {
e.printStackTrace();
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return t;
}



import java.util.List;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;

@JsonInclude(Include.NON_NULL)
public class MuyaLCResultsBean<T> {
public List<T> results;
public String className;
}



String strBody = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
MuyaLCResultsBean<MuyaLCFamilyBindRelationBean> bean = ReadJson(strBody, MuyaLCResultsBean.class);

MuyaLCFamilyBindRelationBean first = bean.results.get(0);   // (2)此处报错,错误请参见下面  
String strResult = first.ToJson();
System.out.println(strResult);


运行至(2)处,出现Exception:
Exception in thread "main" java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to com.aika.kidtracker.cloud.MuyaLCFamilyBindRelationBean
at com.aika.kidtracker.cloud.WebUtilMain.TestCQL(WebUtilMain.java:544)
at com.aika.kidtracker.cloud.WebUtilMain.main(WebUtilMain.java:66)

我的个人推断是,ReadJson()传入的第二个class只是MuyaLCResultsBean,因此,进行到(1)处时,
objectMapper.readValue(_strJson, _class); 
是根本不知道真正要解析的类的具体格式,就默认解析成LinkHashMap了。

请高手帮助,如何修改代码?

6 个解决方案

#1


代码的执行逻辑不能靠猜测的。楼主你得看下ObjectMapper类中的readValue方法的具体实现逻辑,看下方法中对MuyaLCResultsBean类中指定的results列表具体添加了哪种类型的数据。如果方便的话,你可以贴下该方法的关键代码,我再帮你看看。

另外,楼主需要注意的是:在java中泛型只在编译期起作用,在运行阶段泛型会被擦除掉,即运行阶段没有泛型的概念。所以MuyaLCResultsBean类中变量的List<T>用了泛型限制元素类型为T,即在编译期可以限制添加的元素必须为T类型,如MuyaLCResultsBean<MuyaLCFamilyBindRelationBean>类声明后,T就表示MuyaLCFamilyBindRelationBean。但如果是通过反射来处理是可以绕过这一限制的。所以你ObjectMapper类中的readValue操作是可以往results列表中添加LinkedHashMap类型的数据。具体为何会出现这个类型,得具体看你objectMapper.readValue的具体实现。

#2


Jackson不支持泛型。单个bean能正确转型和注入,用List装起来的bean解析之后就是LinkedHashMap。
这个坑坑了我很久,但解决方法意外地简单:把List改成数组就行了。泛型提供的类型检查就没办法用了,可以考虑建公共父类或者干脆用Object,或者在网上抄一个泛型数组的写法。我推荐第一种。

#3


你应该给他设置一个父类,限定一下泛型,例如Collectin<? extend MuyaLCResultsBean>

#4


引用 2 楼 windowsoahil 的回复:
Jackson不支持泛型。单个bean能正确转型和注入,用List装起来的bean解析之后就是LinkedHashMap。
这个坑坑了我很久,但解决方法意外地简单:把List改成数组就行了。泛型提供的类型检查就没办法用了,可以考虑建公共父类或者干脆用Object,或者在网上抄一个泛型数组的写法。我推荐第一种。


是啊,感谢哥们的经验分享。
能否说一下,你推荐的第一种方法(公共父类)的思路和示例代码?多谢 了哈 ~~~

#5


引用 3 楼 airfling 的回复:
你应该给他设置一个父类,限定一下泛型,例如Collectin<? extend MuyaLCResultsBean>


是啊,感谢哥们的回复。
能否说一下,你推荐的父类的思路和示例代码?多谢 了哈 ~~~

#6


如果能确定T可能的类型,比如T可能是Integer和Double,就可以把results的类型改成Number[]。如果是String和Integer这种没有公共父类的,就只能定义为Object[],然后在使用的时候强转

#1


代码的执行逻辑不能靠猜测的。楼主你得看下ObjectMapper类中的readValue方法的具体实现逻辑,看下方法中对MuyaLCResultsBean类中指定的results列表具体添加了哪种类型的数据。如果方便的话,你可以贴下该方法的关键代码,我再帮你看看。

另外,楼主需要注意的是:在java中泛型只在编译期起作用,在运行阶段泛型会被擦除掉,即运行阶段没有泛型的概念。所以MuyaLCResultsBean类中变量的List<T>用了泛型限制元素类型为T,即在编译期可以限制添加的元素必须为T类型,如MuyaLCResultsBean<MuyaLCFamilyBindRelationBean>类声明后,T就表示MuyaLCFamilyBindRelationBean。但如果是通过反射来处理是可以绕过这一限制的。所以你ObjectMapper类中的readValue操作是可以往results列表中添加LinkedHashMap类型的数据。具体为何会出现这个类型,得具体看你objectMapper.readValue的具体实现。

#2


Jackson不支持泛型。单个bean能正确转型和注入,用List装起来的bean解析之后就是LinkedHashMap。
这个坑坑了我很久,但解决方法意外地简单:把List改成数组就行了。泛型提供的类型检查就没办法用了,可以考虑建公共父类或者干脆用Object,或者在网上抄一个泛型数组的写法。我推荐第一种。

#3


你应该给他设置一个父类,限定一下泛型,例如Collectin<? extend MuyaLCResultsBean>

#4


引用 2 楼 windowsoahil 的回复:
Jackson不支持泛型。单个bean能正确转型和注入,用List装起来的bean解析之后就是LinkedHashMap。
这个坑坑了我很久,但解决方法意外地简单:把List改成数组就行了。泛型提供的类型检查就没办法用了,可以考虑建公共父类或者干脆用Object,或者在网上抄一个泛型数组的写法。我推荐第一种。


是啊,感谢哥们的经验分享。
能否说一下,你推荐的第一种方法(公共父类)的思路和示例代码?多谢 了哈 ~~~

#5


引用 3 楼 airfling 的回复:
你应该给他设置一个父类,限定一下泛型,例如Collectin<? extend MuyaLCResultsBean>


是啊,感谢哥们的回复。
能否说一下,你推荐的父类的思路和示例代码?多谢 了哈 ~~~

#6


如果能确定T可能的类型,比如T可能是Integer和Double,就可以把results的类型改成Number[]。如果是String和Integer这种没有公共父类的,就只能定义为Object[],然后在使用的时候强转