为什么Java不抱怨通用地图转换?

Sic*_*ong 5 java generics casting map

Object stringMap = new HashMap<String, String>(){{ put("1", "a"); }};
Map<Integer, String> integerMap = (Map<Integer, String>)stringMap; // Why doesn't Java throw an exception at run-time?

// I know this is not a problem if stringMap is declared as Map<String, String>.
// However, the actual code above was using Spring Bean.
// Map<Integer, String> integerMap = (Map<Integer, String>)context.getBean("map");

System.out.println(integerMap.get(1)); // prints null
System.out.println(integerMap.get("1")); // prints a
Run Code Online (Sandbox Code Playgroud)

Q1.为什么Java允许在运行时进行这样的转换?

Q2.如果使用bean,避免此错误的最佳做法是什么?

Kep*_*pil 11

Q1.因为在运行时,所有generic信息都已被删除,因此这两种Map类型在运行时环境中无法区分.该generics只那里帮助编译器执行类型安全.引用Java教程:

泛型是通过类型擦除实现的:泛型类型信息仅在编译时出现,之后由编译器擦除.这种方法的主要优点是它提供了通用代码和使用非参数化类型(在技术上称为原始类型)的遗留代码之间的完全互操作性.主要缺点是参数类型信息在运行时不可用,并且在与不良遗留代码进行互操作时自动生成的强制转换可能会失败.

Q2.不要使用原始类型的地图.如果必须的话,当你对它们进行类型转换时要非常小心.