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


12

我从一些测验中提取​​了此代码段,使用IDE执行了该代码段,并获得了长久的结果但是正确的答案是Byte,Byte,为什么我得到不同的结果?这个问题与JDK 11有关

public class Client {
    static void doCalc(byte... a) {
        System.out.print("byte...");
    }

    static void doCalc(long a, long b) {
        System.out.print("long, long");
    }

    static void doCalc(Byte s1, Byte s2) {
        System.out.print("Byte, Byte");
    }

    public static void main(String[] args) {
        byte b = 5;
        doCalc(b, b);
    }
}

编辑:

代码在此处获取:Oracle认证概述和样本问题 (页面:13,问题:5)


1
你确定它不是Byte b = 5;一个大写B.
乔普埃根

4
我也很long, long喜欢Java8 ...不确定为什么要诚实,也等待答案:)
sp00m

Answers:


6

因此,如果您遍历Java语言规范来确定编译时的方法签名,则很清楚:

  1. 第一阶段(第15.12.2.2节)执行重载解析,而不允许装箱或拆箱转换或使用可变Arity方法调用。如果在此阶段未找到适用的方法,则处理将继续进行到第二阶段。

  2. 第二阶段(第15.12.2.3节)在允许装箱和拆箱的同时执行重载解析,但仍排除使用可变arity方法调用。如果在此阶段未找到适用的方法,则处理将继续进行到第三阶段。

  3. 第三阶段(第15.12.2.4节)允许将重载与可变arity方法,装箱和拆箱相结合。

因此,从上述步骤可以很明显地看出,在您的第一阶段, Java编译器将找到一个匹配的方法,它做到了doCalc(long a,long b)。您的方法doCalc(Byte s1, Byte s2)在通话过程中需要自动装箱,因此偏好会减少。


1
关于为什么long接受byte,似乎遵循了不断扩大的原始转换docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.2。所以基本上,+widening -boxing -varargs然后+widening +boxing -varargs+widening +boxing +varargs
sp00m

@kbo为什么您认为正确的答案是Byte, Byte
阿米特·贝拉

3
@kbo我猜正确的答案是错误的:)如果可以的话,可能值得向作者指出这个问题。
sp00m

3
@ sp00m我在Oracle的样本中发现了这个问题,请看一看编辑部分
kbo

@kbo哇...不知道该如何继续!
sp00m

2

请阅读有关转换JLS章节

您遇到的情况是,在运行时期间,JVM选择执行扩展转换 byte -> long,因为这可以确保转换不会引起,因此转换更安全RuntimeException

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

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

因此,首选更安全的byte -> long 加宽转换


2
请注意,从byte到的装箱Byte不会导致OutOfMemoryException,因为Byte(-128-127)的所有值都在内部缓存。但这与其他类型可能并不相同,因此根据经验法则,扩大转换优先。
帕维尔·史米尔诺夫

1

为了找到正确的过载,顺序为:

  1. 按参数数量
  2. 装箱/拆箱
  3. 可变参数

所以

  • 如果结果b在哪里。ByteByte, Byte
  • 如果通过new byte[] { b, b },结果将是byte, byte
  • 如果传递两个字节b,则可能从byte 扩展到int到long,结果为long, long
  • 如果消除了长时间的过载,就会Byte, Byte产生结果。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.