Java 将字节参数传递给重载方法

Java 将字节参数传递给重载方法,java,Java,我从一些测试中获取了这个代码片段,使用IDE执行它,得到了一个结果long,long,但正确的答案是Byte,Byte,为什么我得到了不同的结果?这个问题与JDK 11有关 公共类客户端{ 静态void doCalc(字节…a){ 系统输出打印(“字节…”); } 静态无效文件(长a、长b){ 系统输出打印(“长,长”); } 静态void doCalc(字节s1,字节s2){ 系统输出打印(“字节,字节”); } 公共静态void main(字符串[]args){ 字节b=5; doCalc(

我从一些测试中获取了这个代码片段,使用IDE执行它,得到了一个结果long,long,但正确的答案是Byte,Byte,为什么我得到了不同的结果?这个问题与JDK 11有关

公共类客户端{
静态void doCalc(字节…a){
系统输出打印(“字节…”);
}
静态无效文件(长a、长b){
系统输出打印(“长,长”);
}
静态void doCalc(字节s1,字节s2){
系统输出打印(“字节,字节”);
}
公共静态void main(字符串[]args){
字节b=5;
doCalc(b,b);
}
}
编辑:

代码是在这里拍摄的:
(第13页,问题:5)

因此,如果您在编译时使用Java语言来确定方法签名,就会清楚:

  • 第一阶段(§15.12.2.2)在不允许装箱或拆箱转换或使用变量算术的情况下执行重载解析 方法调用。如果在此阶段未找到适用的方法 然后处理继续到第二阶段

  • 第二阶段(§15.12.2.3)在允许装箱和拆箱的同时执行过载解决,但仍然禁止使用变量 arity方法调用。如果在此过程中未找到适用的方法 阶段,然后处理继续到第三阶段

  • 第三阶段(§15.12.2.4)允许重载与可变算术方法、装箱和拆箱相结合


  • 因此,从以上步骤可以清楚地看出,在您的案例中,在第一阶段Java编译器将找到一个匹配的方法,该方法不会
    doCalc(long a,long b)
    。您的方法
    doCalc(字节s1,字节s2)
    在调用过程中需要一个自动装箱,以便获得较少的首选项

    要找到正确的过载,顺序如下:

  • 按参数数量
  • 装箱/拆箱
  • 可变参数
  • 所以

    • 如果
      b
      其中a
      字节
      ,结果将是
      字节,字节
    • 如果通过,将是
      newbyte[]{b,b}
      结果将是
      byte,byte
    • 如果传递两个字节b,则可以从字节到int再到long进行加宽,结果是
      long,long
    • 当长时间重载被删除时,
      Byte,Byte
      结果
      • 请仔细阅读

        您的情况是,在运行时,JVM选择执行加宽转换
        字节->长
        ,因为这样转换更安全,因为它保证不会导致
        运行时异常

        byte
        转换为
        byte
        也称为装箱会导致OutOfMemoryError,因为JVM必须将新对象分配到堆上:

        如果需要分配其中一个包装类(布尔、字节、字符、短、整数、长、浮点或双精度)的新实例,并且可用存储不足,则装箱转换可能会导致OutOfMemoryError


        因此,更安全的
        字节->长
        加宽转换是首选。

        您确定它不是
        字节b=5大写B。我在Java8上也得到了
        long,long
        。。。老实说,不知道为什么,也在等待答案:)关于为什么
        long
        接受
        byte
        的可能重复,似乎遵循了一个扩展的原语转换:。所以基本上,
        +wilding-boxing-varargs
        然后
        +wilding+boxing-varargs
        然后
        +wilding+boxing+varargs
        @kbo为什么你认为正确的答案是
        字节,Byte
        ?@kbo我想正确的答案是不正确的:)如果可以的话,可能值得向作者指出这个问题。@sp00m我在Oracle的示例中发现了这个问题,请查看编辑的part@kbo哇!不知道该怎么办!需要注意的是,从
        byte
        装箱到
        byte
        不会导致
        OutOfMemoryException
        ,因为
        byte
        (-128-127)的所有值都在内部缓存。但它可能与其他类型不同,因此根据经验法则,加宽转换具有优先权。