return-6ren">
gpt4 book ai didi

java - 使用 HashMap 时 Java 11 中的 ClassCastException 而不是 Java 8 中的?

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:52:10 25 4
gpt4 key购买 nike

请看我的代码:

Object longL = 2548214;
Map<String, Object> map = new HashMap<String, Object>(1);
map.put("LongNumber", longL);
List<Map<String, Object>> returnlist = new ArrayList(10);
returnlist.add(map);

List<Object> versionMap1 = new ArrayList(10);
versionMap1.add(returnlist);

List<Map<String, String>> docIdVersionNameMap = new ArrayList<>();
docIdVersionNameMap.addAll((List<Map<String, String>>)versionMap1.get(0));

Map<String, String> versionDoc=docIdVersionNameMap.get(0);

Map<String,String> versionDocInfo=new HashMap<String,String>(1);
versionDocInfo.put(versionDoc.get("LongNumber"),"abc");
System.out.println(versionDocInfo.toString());

在 Java_1.8_60(编译和运行)中,此代码运行良好,但在 Java 11 中编译和运行时,它抛出以下异常:

Exception in thread "main" java.lang.ClassCastException: class java.lang.Integer cannot be cast to class java.lang.String (java.lang.Integer and java.lang.String are in module java.base of l
oader 'bootstrap')
at teststringandlong.Trial.main(Trial.java:35)

Java 11 中关于 HashMap 有什么变化吗?

最佳答案

ClassCastException被扔是正确的。没有抛出它是由 javac 中的错误引起的,已在 JDK 9 中由 JDK-8058199 修复.您的代码在技术上依赖于未被拾取的堆污染,因此无法保证不会中断。

基本上,在 Java 11(但从 9 开始)中,在获取 "LongNumber" 的值后会插入一个额外的转换。从第二行到最后一行的 map 。这:

versionDocInfo.put(versionDoc.get("LongNumber"),"abc");

编译为:

versionDocInfo.put((String) versionDoc.get("LongNumber"),"abc");

使用 javac 1.8.0_162 编译代码时,倒数第二行的字节码是:

 114: aload         7
116: aload 6
118: ldc #6 // String LongNumber
120: invokeinterface #16, 2 // InterfaceMethod java/util/Map.get:(Ljava/lang/Object;)Ljava/lang/Object;
125: ldc #17 // String abc
127: invokeinterface #7, 3 // InterfaceMethod java/util/Map.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;

注意没有 checkcast 120: 之后的说明.但是,当使用 javac 9.0.4 时:

 114: aload         7
116: aload 6
118: ldc #6 // String LongNumber
120: invokeinterface #16, 2 // InterfaceMethod java/util/Map.get:(Ljava/lang/Object;)Ljava/lang/Object;
125: checkcast #17 // class java/lang/String
128: ldc #18 // String abc
130: invokeinterface #7, 3 // InterfaceMethod java/util/Map.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;

注意有一个 checkcast指令在 125: .

这条指令有所不同,因为它基本上是在从 versionDoc 获取值后进行额外的类型检查 map 。基本上这样做:

versionDocInfo.put((String) versionDoc.get("LongNumber"),"abc");

在 Java 11(从 9 开始)中。


如评论中所述; "LongNumber" 的值类型是Integer , 在 Map<String, String> 内由于前面几行未经检查的转换:

docIdVersionNameMap.addAll((List<Map<String, String>>) versionMap1.get(0));

间接转换 Map<String, Object> 的地方到 Map<String, String> ,即使其中一个值是 Integer .不同之处仅在于在从 map 获取值后有一个额外的转换来检查类型。

请注意缺少 checkcastjavac 中的错误,因此使用不同的编译器或不同版本的 javac 进行编译可能会导致不同的行为。

关于java - 使用 HashMap 时 Java 11 中的 ClassCastException 而不是 Java 8 中的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55204967/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com