Java:在某些情况下ClassCastException

tom*_*ski 0 java casting

我有以下代码:

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);
}
Run Code Online (Sandbox Code Playgroud)

这是我的输出:

1234
Exception in thread "main" java.lang.ClassCastException: 
java.lang.Integer cannot be cast to java.util.HashMap
Run Code Online (Sandbox Code Playgroud)

为什么从HashMap到Intger的运行没有错误?

Mik*_*uel 6

为什么从HashMap到Integer的运行没有错误?

你没有从HashMap转换为Integer.你铸造自动装箱 intInteger.

x = (Integer) 1234;
Run Code Online (Sandbox Code Playgroud)

1234是一个int文字,Integer在您尝试将其用作引用类型时自动装入.


然后你返回Integer并得到一个ClassCastException因为它不能被强制转换为a HashMap.

return x;
Run Code Online (Sandbox Code Playgroud)

返回1234,然后在此处进行投射

(HashMap<String,String>) f(before)
Run Code Online (Sandbox Code Playgroud)

哪个失败了.


也许这里存在概念上的错误.

Object x 定义一个可以保存对任何类型对象的引用的框.

f(myHashMap)启动一个函数调用,x使用对哈希映射的引用填充该框.

x = (Integer) 1234扔出盒子的内容,并用一个引用替换它Integer.这是合法的,因为声明Object x确定该框可以包含对任何对象的引用(或者none:)null.

然后x从其f返回类型返回Object并在此处使用它

HashMap<String, String> after = (HashMap<String, String>) f(before)
Run Code Online (Sandbox Code Playgroud)

它取出了可以包含任何内容的框的内容,并确保它可以放在一个名为after只能包含HashMap<?,?>s 的框中.

这不起作用,因为返回的引用f(before)不适合该框.因此在运行时异常.


您可以将程序缩减到下面以了解正在发生的事情.

Object x = (Integer) Integer.valueOf(1234);               // Unnecessary cast.
HashMap<String, String> m = (HashMap<String, String>) x;  // Fails due to type-unsafe cast.
Run Code Online (Sandbox Code Playgroud)

如果你不使用Object,你可能会得到编译器向你解释的问题

Integer x = (Integer) Integer.valueOf(1234);
HashMap<String, String> m = (HashMap<String, String>) x;
Run Code Online (Sandbox Code Playgroud)