为什么在方法的重载中加宽Boxing和var-args?

我正在准备进行SCJP考试,在学习拓宽部分的时候,考虑到加宽超过Boxing和Var-args,但是没有明确的解释。 尝试搜索但没有得到任何更好的答案。

我得到的一个答案是因为编译器在选择较新的样式之前选择较旧的样式。 但我不相信。

编辑:我知道扩大比拳击和var-args更喜欢。 但为什么是我的问题。 其中我知道一个。 任何其他原因。

是的,由于兼容性要求,编译器“选择旧样式而不是新样式”。 想象一下在Java 5出现之前编写的一些代码,它们在Java 5下编译时突然发生了行为变化! 那会很糟糕。

自Java诞生以来,转换范围不断扩大,但autoboxing和varargs是Java 5的新function。

这是一个例子:

class Widen { private static void widen(long k) { System.out.println("Converted to long: " + k); } private static void widen(int ... k) { System.out.println("Converted to varargs: " + k); } private static void widen(Integer k) { System.out.println("Converted to Integer: " + k); } public static void main(String ... args) { int value = 3; widen(value); // Output: Converted to long: 3 } } 

所以这一切都意味着它会在自动装箱和使用varargs之前扩大。 如果我们用long参数取出widen的方法,它会在varargs之前选择自动装箱。

编译器必须与以前版本的Java保持兼容。 最重要的是,编译器选择对参数进行最高性能/最小的更改。 促进创建包装器对象的另一个原始节拍,并且打败创建关于内存使用和性能的数组。

扩展性能更好的原因是因为签名扩展是一个简单的操作,对大多数CPU来说是一条指令。 Boxing需要堆分配,并且盒装对象的访问成本更高,至少需要额外的内存访问。

即使没有兼容性问题,在我看来,你希望语言首先选择最快的过载,只要这种行为不会产生任何更糟糕的问题。

我不了解你,但我更倾向于编译器将我的byte作为int不是Byte传递。 考虑开销。 而varargs也需要拳击。

换句话说,原因是效率。 语言设计更喜欢更有效的调用机制,它不需要它来分配盒装项目。

你问,’要求’? varargs函数期望获取Object数组,并且不能包含基本类型。

兼容性也不是一个坏的原因。

拓宽节拍拳击,拳击节拍仿制药,仿制药打败varargs

 class Widen { private static widen(long k) { System.out.println("Converted to long: " + k); } private static widen(int ... k) { System.out.println("Converted to varargs: " + k); } private static widen(Integer k) { System.out.println("Converted to Integer: " + k); } public static void main(String ... args) { int value = 3; widen(value); // Output: Converted to long: 3 } } 

解决以上问题:

拓宽节拍拳击,拳击节拍varargs

输出将转换为长:3