0

I have following code:

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);
}

And this is my output:

1234
Exception in thread "main" java.lang.ClassCastException: 
java.lang.Integer cannot be cast to java.util.HashMap

Why does casting from HashMap to Intger run with no error?

3 Answers 3

6

Why does casting from HashMap to Integer runs with no error?

You're not casting from a HashMap to Integer. You're casting an auto-boxed int to an Integer.

x = (Integer) 1234;

1234 is an int literal which is auto-boxed into an Integer when you try to use it as a reference type.


You then return that Integer and get a ClassCastException because it cannot be cast to a HashMap.

return x;

returns 1234, and this is then cast here

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

which fails.


Maybe there's a conceptual error here.

Object x defines a box that can hold a reference to any type of object.

f(myHashMap) starts a function call that fills the box x with a reference to a hash map.

x = (Integer) 1234 throws out the contents of the box and replaces it with a reference to an Integer. This is legal because the declaration Object x establishes that that box can contain a reference to any object (or none:null).

You then return x from f whose return type is Object and use it here

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

which is taking the contents of a box that can contain anything, and making sure that it can fit in a box named after that can only contain HashMap<?,?>s.

That doesn't work, because the reference returned by f(before) does not fit in that box. Hence the exception at runtime.


You can reduce your program to the below to understand what's going on.

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

and if you eliminate the use of Object, you will probably get the problem explained to you by the compiler

Integer x = (Integer) Integer.valueOf(1234);
HashMap<String, String> m = (HashMap<String, String>) x;
Sign up to request clarification or add additional context in comments.

Comments

1

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

Here autoboxing is done so int is converted to Integer object and then casted to Object.Since Object is super type of Integer it is okay.

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

here f() method returns Object and you are trying to cast this to Integer.Integer is not super type of Object.So you are getting ClassCastException.

According to ClassCastException

Thrown to indicate that the code has attempted to cast an object to a subclass of which it is not an instance. For example, the following code generates a ClassCastException:

 Object x = new Integer(0);
 System.out.println((String)x);

Comments

0

x = (Integer) 1234; //There happens autoboxing. Compiler converts primitive int to Integer. It looks like f() always returns Objcet that is-a Integer. And than you try to cast it to HashMap. Compiler doesn't complain that you try to cast Object(reference type of f() return value) to HashMap. However object type is Integer and it fails in runtime.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.