代码之家  ›  专栏  ›  技术社区  ›  GuruKulki

为什么在方法的重载中,加宽会同时胜过装箱参数和var参数?

  •  8
  • GuruKulki  · 技术社区  · 15 年前

    我正在准备一个SCJP考试,在学习扩展部分时,假设在重载中,扩展比装箱和var参数都强,但没有明确的解释。尝试了搜索,但没有得到更好的答案。

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

    编辑:我知道加宽比装箱和var参数更可取。但我的问题是什么?其中我知道一个。其他原因。

    7 回复  |  直到 11 年前
        1
  •  16
  •   C. K. Young    15 年前

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

    自Java诞生以来,就有了广泛的转换,但是自动装箱和VARARGS对于Java 5来说是新的。

        2
  •  5
  •   Luiggi Mendoza    11 年前

    下面是一个例子:

    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之前,它会变宽。如果采用长参数加宽的方法,在变容器之前就选择了自动氧化。

        3
  •  1
  •   rsp    15 年前

    编译器必须保持与以前版本的Java的兼容性。除此之外,编译器选择对参数的最有效/最小更改。升级到另一个原语比创建包装对象更重要,这比创建与内存使用和性能相关的数组更重要。

        4
  •  0
  •   ergosys    15 年前

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

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

        5
  •  0
  •   bmargulies    15 年前

    我不了解你,但我更希望编译器通过我的 byte 作为一个 int 比A Byte . 考虑一下开销。varargs也需要拳击。

    换句话说,原因是效率。语言设计更倾向于更有效的调用机制,而不需要它来分配装箱项。

    “需要”,你问?varargs函数期望获得 Object ,不能包含基元类型。

    兼容性也是一个不错的理由。

        6
  •  0
  •   Dmitriy Kochergin    14 年前

    不断扩大的节拍拳击, 拳击胜过仿制药, 仿制药击败瓦拉格斯

        7
  •  -2
  •   takrl cck    13 年前
    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