Java 为什么可以投射不同类型的贴图?

Java 为什么可以投射不同类型的贴图?,java,casting,map,Java,Casting,Map,我今天遇到了一件奇怪的事,我不太明白。以这段代码为例: Object iMap = new HashMap<Integer, Object>() {{ put(5, "thing1"); put(6, "thing2"); }}; Map<String, Object> sMap = (Map<String, Object>)iMap; // No error, prints out java.lang.Integer: System.out

我今天遇到了一件奇怪的事,我不太明白。以这段代码为例:

Object iMap = new HashMap<Integer, Object>() {{
    put(5, "thing1");
    put(6, "thing2");
}};
Map<String, Object> sMap = (Map<String, Object>)iMap;

// No error, prints out java.lang.Integer:
System.out.println(new ArrayList(sMap.keySet()).get(0).getClass().getName();

// No error, prints out 5:
Object key = new ArrayList<String>(sMap.keySet()).get(0);
System.out.println(key.toString());

// ClassCastException:
String s = new ArrayList<String>(sMap.keySet()).get(0);
Object iMap=new HashMap(){{
放置(5,“东西1”);
放置(6,“东西2”);
}};
Map sMap=(Map)iMap;
//无错误,打印出java.lang.Integer:
System.out.println(新的ArrayList(sMap.keySet()).get(0.getClass().getName());
//无错误,打印出5:
objectkey=newarraylist(sMap.keySet()).get(0);
System.out.println(key.toString());
//ClassCastException:
字符串s=newarraylist(sMap.keySet()).get(0);
那么,给出了什么?为什么我可以将一个带有Integer类型键的映射转换为String类型的映射而没有任何问题?这不应该引发错误吗?为什么我甚至可以转换为
ArrayList而仍然没有错误?它应该是一个只包含字符串的列表,但我可以从中检索整数


我对此感到有点困惑,我想知道这里是否有人对这些类的内部工作有足够的了解来帮助我。

您的代码的前四行不会编译,因为iMap必须声明为映射才能调用get(…)等方法但您的另一个问题说明了为什么在声明变量时使用泛型很重要。因此,如果您这样声明iMap:

  Map<Integer, Object> iMap = new HashMap<Integer, Object>();
Map iMap=newhashmap();
当您尝试在此处强制转换时,编译器会正确地抱怨:

Map<String, Object> sMap = (Map<String, Object>)iMap;
Map sMap=(Map)iMap;
您可以将
Map
强制转换为
Map
“没有任何问题”…直到您尝试使用它

问题从这一行开始:

Map<String, Object> sMap = (Map<String, Object>)iMap;
sMap实际上指的是在其条目中有整数作为键的映射。当您实际要取出其中一个键时,它是一个整数,java随后试图将其分配给字符串…砰

顺便说一句,此部分不编译:

Object iMap = new HashMap<Integer, Object>();
iMap.put(5, "thing1");
iMap.put(6, "thing2");
Object iMap=new HashMap();
iMap.put(5,“thing1”);
iMap.put(6,“thing2”);
您需要将iMap强制转换为
Map
,如下所示:

Object iMap = new HashMap<Integer, Object>();
((Map<Integer, Object>)iMap).put(5, "thing1");
((Map<Integer, Object>)iMap).put(6, "thing2");
Object iMap=new HashMap();
(地图)iMap.put(5,“thing1”);
(地图)iMap.put(6,“thing2”);

您的代码的前四行无法编译。iMap至少需要声明为映射。@气垫船不正确。您自己试试这段代码。它可以编译。@JakeKing:我在输入注释之前测试过它。但这不重要,因为这是一个基本的Java错误,它不应该编译。不,不会。正如我在问题上所评论的那样在上,我测试了这个。它编译并运行。不是用我熟悉的任何Java编译器。我收回它。我的代码略有不同,我会更新我的第一篇文章。对不起。啊,当然!我在使用泛型时似乎总是忘了这一点。我会尽快接受它。(StackOverflow太神奇了。)是的,我修复了“未编译”的问题当我对此进行一个小测试时,我使用了懒惰的“双括号初始化”方法。
Object iMap = new HashMap<Integer, Object>();
((Map<Integer, Object>)iMap).put(5, "thing1");
((Map<Integer, Object>)iMap).put(6, "thing2");