英文:
Why wrong casting of generics won't produce exception in java?
问题
我有这段代码:
Map<Object, Object> map;
...
List<String> strings = new ArrayList<>();
Object tmp = map.get("strings");
strings.addAll((List<String>) tmp);
如果 tmp 的类型是 List<String>
,代码能够正常运行。但如果 tmp 的类型是 List<Map>
,为什么程序不会抛出异常呢?
英文:
I have this code:
Map<Object, Object> map;
...
List<String> strings = new ArrayList<>();
Object tmp = map.get("strings");
strings.addAll((List<String>) tmp);
It works fine if tmp is of type List<String>
, but why the program won't produce exception if tmp is of type List<Map>
?
答案1
得分: 3
一个将对象强制转换为 List<String>
的操作实际上是将其转换为 List
。在运行时,String
不再存在。IDE 确实对此发出了警告。稍后在使用 strings
项时可能会出现运行时异常。
另一件事,List<Map>
缺少泛型参数,当裸露地使用,比如 List list
,编译器会回退到非泛型解释,消除所有关于泛型类型违规的警告。
针对您的用例:一种带有不同类型变量的简单的“变量”映射可能会有问题。请提供您自己的运行时类型信息,也许可以回退到(实际上不需要的)数据转移:
List<?> list = (List<?>) map.get("strings");
List<String> list2 = list.stream().map(String.class::cast).collect(Collectors.toList());
英文:
A cast to List<String>
of an Object actually is a cast to List
. At runtime String no longer is there. The IDE did warn about this. Later on when working with strings
items a runtime exception may be expected.
Another thing, List<Map>
misses generic parameters, and when used bare, like List list
, the compiler reverts to non-generic interpretation, dropping all warning of generic type violations.
For your use-case: a kind of simple "variable" map with differently typed variables is problematic. Provide your own run-time type info, and maybe revert to (actually unneeded) shoveling of data:
List<?> list = (List<?>) map.get("strings");
List<String> list2 = list.stream().map(String.class::cast).collect(Collectors.toList());
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论