java.lang java.util.String cannot be cast to java.util.HashMap

8339人阅读
Java基础(22)
使用stackoverflow上的代码描述这个问题:
ObjectMapper mapper = new ObjectMapper();
List&ConsultantDto& list = new ArrayList&ConsultantDto&();
list = mapper.readValue(con.getInputStream(), ArrayList.class);
} catch (JsonGenerationException e) {
e.printStackTrace();
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
转换不会出现错误,但是获取具体数据时会抛出异常:
System.out.println(list.get(0));
System.out.println(list.get(0).getForename());
&span style=&color:#FF0000;&&&strong&java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to com.xxx.xxx.web.dto.rp.ConsultantDto&/strong&&/span&异常信息很少。
解决办法:
List&ConsultantDto& myObjects =
mapper.readValue(jsonInput, new TypeReference&List&ConsultantDto&&(){});
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:79005次
积分:1882
积分:1882
排名:第19734名
原创:120篇
(1)(1)(5)(1)(1)(2)(1)(1)(1)(1)(1)(1)(1)(1)(1)(7)(101)今天遇到一个小问题,让我感觉Java的泛型(因为背负了历史的包袱导致的)有点鸡肋啊。
我们经常会遇到要一些自定义的key-value字符串,比如:
"key1:1k;key2:2;key3:3"
通常编码的时候会将它转换为一个Map这样方便操作,因为key和value的类型不一定(可能是int也可能是String等),于是我用Java写了一个简单的泛型方法:
@SuppressWarnings("unchecked")
public static &K, V& Map&K, V& getMap(String source, String firstSplit, String secondSplit) {
Map&K, V& result = new HashMap&K, V&();
if (source.equals("")) {
String[] strings = source.split(firstSplit);
for (int i = 0; i & strings. i++) {
String[] tmp = strings[i].split(secondSplit);
if (tmp.length == 2) {
result.put((K) tmp[0], (V) tmp[1]);
// System.out.println("(K) tmp[0]:"+((K) tmp[0]).getClass());
// System.out.println("(V) tmp[1]:"+((V) tmp[1]).getClass());
看上去貌似可以正常工作的,用上面的字符串举例子,我应该希望得到的是Map&String, Integer&这样一个结果。
String test = "key1:1k;key2:2;key:3";
Map&String, Integer& map = getMap(test, ";", ":");
for (Entry&String, Integer& entry : map.entrySet()) {
Integer value = entry.getValue();
上面的代码编译时完全没问题的,但是一运行:
Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer at ossp.demo.generic.GenericDemo.main(GenericDemo.java:38)
报的是类型转换错误,String不能转换为Interger类型?但是明明entry.getValue()结果就是Interger类型啊,难道不是吗?
一开始很疑惑,但稍微一想就明白了,哦!Java泛型用的是&擦除&法,完全是编译期的,运行时已经没有泛型参数的类型信息了,也就是说运行时所有的泛型参数都被替换成了Object(如果有泛型约束(.net是这么叫的)是不是就替换成上限类型?)所以上面的泛型方法其实就等价于:
public static Map&Object, Object& getMap(String source, String firstSplit, String secondSplit) {
Map&Object, Object& result = new HashMap&Object, Object&();
if (source.equals("")) {
String[] strings = source.split(firstSplit);
for (int i = 0; i & strings. i++) {
String[] tmp = strings[i].split(secondSplit);
if (tmp.length == 2) {
result.put((Object) tmp[0], (Object) tmp[1]);
也就是说entry.getValue();返回的其实是一个Object对象的,它的类型应该是java.lang.String,于是我想那么这样转换一下应该可以了:
Integer value = Integer.valueOf(entry.getValue());
但是让我郁闷的是仍然报之前的错误,鼠标点上去,智能提示看执行的应该是参数为int的重载反复,额,又绕回去了。
那怎么才能得到我想得到那个Integer的value呢???最后我发现这样是可以的:
Integer value = Integer.valueOf(String.valueOf(entry.getValue()));
我靠!这太让我无语了。不光如此我发现直接执行下面这行代码也会报类型转换错误:
System.out.println(entry.getValue().getClass());
既然entry.getValue()的类型是java.lang.String,为什么Map&String, Integer& map = getMap2(test, ";", ":");和Entry&Object, Integer& entry : map.entrySet()这两行又都能编译通过呢?想想还是万恶的&类型擦除&的原因,我们先看看C#里的情况。
Dictionary&string, int& dic1 = new Dictionary&string, int&();
Dictionary&string, double& dic2 = new Dictionary&string, double&();
Console.WriteLine(dic1);
Console.WriteLine(dic2);
我们知道.NET泛型将每个类型参数理解为一个独立的类型,所以上面dic1和dic2的类型是不一样的:
但是在Java里因为&类型擦除&实际上Map&String,Interger&和Map&String,Double&的类型都是:java.util.HashMap
Map&String, Integer& map1 = new HashMap&String, Integer&();
Map&String, Double& map2 = new HashMap&String, Double&();
System.out.println(map1.getClass());
System.out.println(map2.getClass());
这样看来上面的代码编译通过是必须的,那么这智能提示有什么意义呢(编译期的YY?)。
我们看看同样的问题C#是怎么解决的。一开始我以为像Java那样直接强制类型转换就可以:
或者这样:
这些都是不行的。但是只要运行运行时还有类型参数的信息,那么肯定是有办法办到的,.NET中库中就有现成的这样一个方法:Convert.ChangeType,于是我们可以写出下面这个辅助泛型方法:
static V GenericCast&U, V&(U obj)
return (V)Convert.ChangeType(obj, typeof(V));
于是乎为了解决我的问题,我可以写这样一个泛型方法了:
   static Dictionary&K, V& ToMap&K, V&(string source, string firstSplit, string secondSpilt)
Dictionary&K, V& result = new Dictionary&K, V&();
if (String.IsNullOrEmpty(source))
string[] info1 = source.Split(new string[] { firstSplit }, StringSplitOptions.RemoveEmptyEntries);
foreach (var item in info1)
string[] info2 = item.Split(new string[] { secondSpilt }, StringSplitOptions.RemoveEmptyEntries);
if (info2.Length == 2)
result.Add(GenericCast&string, K&(info2[0]), GenericCast&string, V&(info2[1]));
string test = "key1:1.1;key2:2;key3:3";
Dictionary&string, double& map = ToMap&string, double&(test, ";", ":");
foreach (var item in map)
Console.WriteLine(item.Key + ":" + item.Value);
并不是想黑Java,只是之前用C#的泛型用的比较爽,用Java的总感觉有点食之无味,弃之可惜。
阅读(...) 评论()

我要回帖

更多关于 java class cast 的文章

 

随机推荐