有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

为什么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


共 (2) 个答案

  1. # 1 楼答案

    几乎可以肯定的是,rawtypes正在某处被使用,而且有一个Integer正在潜入地图

    最简单的方法是将configMap的初始化替换为

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

    如果在映射中插入了String以外的内容,它实际上会抛出一个异常。我个人不会在生产代码中使用它,但这可能是“排除”bug的最简单方法;您将获得一个异常和一个堆栈跟踪,以确定插入Integer的确切位置

    目前,泛型通过类型擦除实现的方式意味着没有任何东西可以阻止非String值插入到映射中。编译器会做出一些努力来阻止它,但是rawtypes和遗留代码可以绕过它。不过,使用Collections.checkedMap将迫使解决这个问题

  2. # 2 楼答案

    Louis Wasserman已经解释了你问题的可能原因

    我只想指出,在你的问题中,你的想法有几个缺陷

    Why is Java automatically casting from String to Integer when reading LinkedHashMap

    首先,不能从String强制转换为Integer。对于Java引用类型,只有当对象是某个类型的实例或该类型的子类型时,才能将该对象强制转换为该类型。String类型不是Integer的子类型,因此JVM的操作语义禁止这样的强制转换——如果您编写了尝试这样做的可编译代码,您将得到运行时异常

    第二,在LinkedHashMap中没有任何东西。。。或者任何其他collections类,元素/键/值实例从String转换为Integer,而无需您告诉它。行为良好的(Java)API不能做这种事情

    这让我们回到Louis的诊断——某些东西(比如你的代码)将Integer对象作为一个值添加了进来。如果使用原始类型或抑制/忽略“未检查的转换”警告,就会发生这种情况