我有以下代码:
static Object f(Object x) {
x = (Integer) 1234; // <- it runs OK (why?)
System.out.println(x);
return x;
}
public static void main(String[] args) {
HashMap<String, String> before = new HashMap<String, String>();
before.put("a", "b");
HashMap<String, String> after = (HashMap<String,String>) f(before); // <- it fails
System.out.println(after);
}
这是我的输出:
1234
Exception in thread "main" java.lang.ClassCastException:
java.lang.Integer cannot be cast to java.util.HashMap
为什么从HashMap到Intger的运行没有错误?
答案 0 :(得分:6)
为什么从HashMap到Integer的运行没有错误?
您不是从HashMap转换为Integer。您正在向int
投射auto-boxed Integer
。
x = (Integer) 1234;
1234
是一个int
字面值,当您尝试将其用作参考类型时会自动装入Integer
。
然后,您返回Integer
并获得ClassCastException
,因为它无法转换为HashMap
。
return x;
返回1234,然后在此处投射
(HashMap<String,String>) f(before)
失败了。
这里可能存在概念错误。
Object x
定义了一个可以保存对任何类型对象的引用的框。
f(myHashMap)
启动一个函数调用,使用哈希映射的引用填充框x
。
x = (Integer) 1234
会抛出框中的内容,并将其替换为对Integer
的引用。这是合法的,因为声明Object x
确定该框可以包含对任何对象的引用(或者没有:null
)。
然后,您从x
返回f
,其返回类型为Object
并在此处使用
HashMap<String, String> after = (HashMap<String, String>) f(before)
获取可以包含任何内容的框的内容,并确保它可以放在名为after
的只能包含HashMap<?,?>
的框中。
这不起作用,因为f(before)
返回的引用不适合该框。因此在运行时发生异常。
您可以将程序缩减到下面,以了解正在发生的事情。
Object x = (Integer) Integer.valueOf(1234); // Unnecessary cast.
HashMap<String, String> m = (HashMap<String, String>) x; // Fails due to type-unsafe cast.
如果你不使用Object
,你可能会得到编译器解释的问题
Integer x = (Integer) Integer.valueOf(1234);
HashMap<String, String> m = (HashMap<String, String>) x;
答案 1 :(得分:1)
1. x = (Integer) 1234; // <- it runs OK (why?)
此处进行了自动装箱,因此int
转换为Integer
对象,然后转换为Object
。由于Object
是Integer
的超级类型,因此可以。
2.HashMap<String, String> after = (HashMap<String,String>) f(before); // <- it fails
此处f()
方法返回Object
,您尝试将其转换为Integer
。Integer
不是Object
的超级类型。所以你得到了ClassCastException
。
抛出以指示代码已尝试将对象强制转换为不是实例的子类。例如,以下代码生成ClassCastException:
Object x = new Integer(0);
System.out.println((String)x);
答案 2 :(得分:0)
x =(整数)1234; //发生了自动装箱。编译器将原始int转换为Integer。 看起来f()总是返回Objcet,它是一个整数。而不是你试图把它投射到HashMap。编译器不会抱怨您尝试将Object(f()返回值的引用类型)强制转换为HashMap。但是对象类型是Integer,它在运行时失败。