Reputation: 13
java version:
java version "1.8.0_211" Java(TM) SE Runtime Environment (build 1.8.0_211-b12) Java HotSpot(TM) 64-Bit Server VM (build 25.211-b12, mixed mode)
Test.java
package com.test.cast;
import java.util.HashMap;
import java.util.Map;
public class Test {
public static Map<String, Object> MAP = new HashMap<>(2);
static {
MAP.put("int", 1);
MAP.put("string", "2");
}
public static void main(String[] args) {
// throws ClassCastException
String.valueOf(get("int"));
}
public static <T> T get(String k) {
Object o = MAP.get(k);
T o1 = (T) o;
return o1;
}
}
the code throws ClassCastException
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to [C
at com.test.cast.Test.main(Test.java:17)
Test.class
public class Test {
public static Map<String, Object> MAP = new HashMap(2);
public Test() {
}
public static void main(String[] args) {
// why char[]
String.valueOf((char[])get("int"));
}
public static <T> T get(String k) {
Object o = MAP.get(k);
return o;
}
static {
MAP.put("int", 1);
MAP.put("string", "2");
}
}
why does the java compiler choose to use char[]
why not use String.valueOf(int)
Upvotes: 1
Views: 58
Reputation: 271185
This is because the compiler prefers the overload that doesn't require a boxing/unboxing conversion to occur.
The overload resolution algorithm roughly goes like this (an adaptation of this section in the spec):
First find the applicable overloads without considering boxing and unboxing, or variable arity parameters (varargs).
If nothing is found, find the applicable overloads considering boxing and unboxing, but not varargs.
If still nothing is found, consider both boxing and unboxing, and varargs.
char[]
was selected, because no unboxing from T
was needed - char[]
is a reference type, and so is T
. int
, on the other hand, is a primitive type. To select the int
overload, T
would need to be inferred as the reference type Integer
, because type parameters cannot be primitive types. Then an unboxing conversion has to occur, to convert it to an int
.
If there was only the int
overload, it would have been selected.
Upvotes: 2