繁体   English   中英

为什么在读取LinkedHashMap时Java自动将String转换为Integer

[英]Why is Java automatically casting from String to Integer when reading 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 ,表明您不能从IntegerString 这很合理,但是值的类型是String。

有没有办法强制Java将这个值保留为String

几乎可以肯定,原始类型正在某处使用,并且有一个Integer潜入了地图。

标识的最简单的方法Integer是越来越插入地图取代的初始化configMap

Map<String, String> configMap = Collections.checkedMap(
  new LinkedHashMap<String, String>(), String.class, String.class);

如果将String以外的内容插入到映射中,则实际上将引发异常。 我不会在生产代码中亲自使用它,但这可能是“吸出”该错误的最简单方法。 您将获得一个异常和一个堆栈跟踪,以了解Integer确切插入位置。

就目前而言,使用类型擦除实现泛型的方式意味着实际上没有什么可以阻止将非String值插入到映射中。 编译器做了一些努力来阻止它,但是原始类型和遗留代码可以解决它。 但是,使用Collections.checkedMap将强制执行此问题。

Louis Wasserman解释了您出现问题的可能原因。

我只想指出,您在思考问题时存在一些缺陷。

为什么在读取LinkedHashMap时Java自动将String转换为Integer

首先,您不能从String转换为Integer 使用Java引用类型,仅当对象是该类型的实例或该类型的子类型时,才可以将对象转换为该类型。 String类型不是Integer的子类型,因此JVM的操作语义禁止这样的强制转换-如果编写尝试执行此操作的可编译代码,则会出现运行时异常。

其次, LinkedHashMap ...或任何其他集合类中没有任何东西可以元素/键/值实例从StringInteger而无需您通知。 行为良好的(Java)API不会做这种事情。

这使我们回到了Louis的诊断-某些东西(例如您的代码)已经添加了Integer对象作为值。 如果您使用原始类型或禁止/忽略“未经检查的转换”警告,则可能发生这种情况。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM