![](/img/trans.png)
[英]Why does the Java compiler 11 use invokevirtual to call private methods?
[英]why does the java compiler choose to use char[]
java 版本:
java 版本“1.8.0_211”Java(TM) SE 运行时环境(内部版本 1.8.0_211-b12) Java HotSpot(TM) 64 位服务器 1 虚拟机(内部版本 25.211-b)
测试.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;
}
}
代码抛出 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)
测试.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");
}
}
为什么 java 编译器选择使用 char[]
为什么不使用 String.valueOf(int)
这是因为编译器更喜欢不需要装箱/拆箱转换的重载。
重载解决算法大致是这样的(规范中本节的改编):
首先找到适用的重载,而不考虑装箱和拆箱,或可变参数(varargs)。
如果没有找到,请在考虑装箱和拆箱时找到适用的重载,而不是可变参数。
如果仍然没有找到,请考虑装箱和拆箱以及可变参数。
选择char[]
是因为不需要从T
拆箱 - char[]
是引用类型, T
也是如此。 另一方面, int
是原始类型。 对于 select int
重载,需要将T
推断为引用类型Integer
,因为类型参数不能是原始类型。 然后必须进行拆箱转换,将其转换为int
。
如果只有int
重载,它就会被选中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.