为什么Java在读取LinkedHashMap时会自动从字符串转换为整数
我的Java应用程序显示了一些奇怪的行为,我很难找到解决方案
此代码段获取LinkedHashMap
的内容,其中键和值都是String
类型,并将它们写入文本文件configWriter
属于PrintWriter
类型
for (Map.Entry<String, String> entry : configMap.entireSet()) {
configWriter.println(entry.getKey() + "=" + entry.getValue());
}
地图被宣布为:
LinkedHashMap<String, String> configMap = new LinkedHashMap<String, String>();
它通过使用Scanner
类从文本文件读取令牌来填充
映射中的一个值是只包含数字(整数)的String
,但是当循环到达该值时,它抛出一个ClassCastException
,表示不能从Integer
转换到String
。这很有道理,但值的类型是String
有没有办法强迫Java将这个值保持为String
# 1 楼答案
几乎可以肯定的是,rawtypes正在某处被使用,而且有一个
Integer
正在潜入地图最简单的方法是将
configMap
的初始化替换为如果在映射中插入了
String
以外的内容,它实际上会抛出一个异常。我个人不会在生产代码中使用它,但这可能是“排除”bug的最简单方法;您将获得一个异常和一个堆栈跟踪,以确定插入Integer
的确切位置目前,泛型通过类型擦除实现的方式意味着没有任何东西可以阻止非
String
值插入到映射中。编译器会做出一些努力来阻止它,但是rawtypes和遗留代码可以绕过它。不过,使用Collections.checkedMap
将迫使解决这个问题# 2 楼答案
Louis Wasserman已经解释了你问题的可能原因
我只想指出,在你的问题中,你的想法有几个缺陷
首先,不能从
String
强制转换为Integer
。对于Java引用类型,只有当对象是某个类型的实例或该类型的子类型时,才能将该对象强制转换为该类型。String
类型不是Integer
的子类型,因此JVM的操作语义禁止这样的强制转换——如果您编写了尝试这样做的可编译代码,您将得到运行时异常第二,在
LinkedHashMap
中没有任何东西。。。或者任何其他collections类,将元素/键/值实例从String
转换为Integer
,而无需您告诉它。行为良好的(Java)API不能做这种事情这让我们回到Louis的诊断——某些东西(比如你的代码)将
Integer
对象作为一个值添加了进来。如果使用原始类型或抑制/忽略“未检查的转换”警告,就会发生这种情况