0

私は次のコードを持っています:

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 へのキャストがエラーなしで実行されるのはなぜですか?

4

3 に答える 3

6

HashMap から Integer へのキャストがエラーなしで実行されるのはなぜですか?

HashMap から Integer にキャストしていません。自動ボックス化 intされた を にキャストしていIntegerます。

x = (Integer) 1234;

1234参照型として使用しようとするとint、自動的に にボックス化されるリテラルです。Integer


aにキャストできないため、それを返し、Integera を取得します。ClassCastExceptionHashMap

return x;

1234 を返し、これがここにキャストされます

(HashMap<String,String>) f(before)

これは失敗します。


たぶん、ここに概念的なエラーがあります。

Object x任意のタイプのオブジェクトへの参照を保持できるボックスを定義します。

f(myHashMap)xボックスをハッシュマップへの参照で埋める関数呼び出しを開始します。

x = (Integer) 1234ボックスの内容を破棄し、 への参照に置き換えますIntegerObject xこれは、そのボックスが任意のオブジェクト (またはなし: ) への参照を含むことができることを宣言が確立するため、正当ですnull

次に、戻り値の型が であるxfromを返し、ここで使用しますfObject

HashMap<String, String> after = (HashMap<String, String>) f(before)

afterこれは、何でも含むことができるボックスの内容を取得し、sのみを含むことができるという名前のボックスに収まるようにします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;
于 2013-09-12T14:45:09.480 に答える
1

1. x = (Integer) 1234; // <- it runs OK (why?)

ここでオートボクシングが行われるので、オブジェクトにint変換されてからキャストされます。はスーパータイプなので大丈夫です。 IntegerObjectObjectInteger

2.HashMap<String, String> after = (HashMap<String,String>) f(before); // <- it fails

heref()メソッドが返さObjectれ、これを にキャストしようとしていIntegerます。IntegerのスーパータイプではありませObjectClassCastException

ClassCastExceptionによると

コードがオブジェクトをインスタンスではないサブクラスにキャストしようとしたことを示すためにスローされます。たとえば、次のコードは ClassCastException を生成します。

 Object x = new Integer(0);
 System.out.println((String)x);
于 2013-09-12T14:47:29.583 に答える
0

x = (整数) 1234; //オートボクシングが発生します。コンパイラはプリミティブ int を Integer に変換します。f() は常に整数である Objcet を返すようです。そして、それを HashMap にキャストしようとします。Object (f() 戻り値の参照型) を HashMap にキャストしようとしても、コンパイラは文句を言いません。ただし、オブジェクト タイプは Integer であり、実行時に失敗します。

于 2013-09-12T14:49:16.013 に答える