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

时间:2010-01-24 17:43:30

标签: java

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

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

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

7 个答案:

答案 0 :(得分:16)

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

自Java诞生以来,扩展转换已经出现,但自动装箱和varargs是Java 5的新功能。

答案 1 :(得分:5)

以下是一个例子:

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之前选择自动装箱。

答案 2 :(得分:1)

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

答案 3 :(得分:0)

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

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

你问,

'需要'? varargs函数期望获得Object的数组,并且不能包含基本类型。

兼容性也不是一个坏理由。

答案 4 :(得分:0)

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

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

答案 5 :(得分:0)

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

答案 6 :(得分:-2)

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

输出将是 转换为long:3