猿问

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

我从一些测验中获取了这段代码片段,使用 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)


holdtom
浏览 113回答 3
3回答

萧十郎

因此,如果您仔细阅读用于在编译时确定方法签名的 Java 语言规范,就会清楚:第一阶段(第 15.12.2.2 节)执行重载解析,不允许装箱或拆箱转换或使用变量 arity 方法调用。如果在此阶段没有找到适用的方法,则处理继续到第二阶段。第二阶段(第 15.12.2.3 节)执行重载解析,同时允许装箱和拆箱,但仍然阻止使用变量 arity 方法调用。如果在此阶段没有找到适用的方法,则处理继续到第三阶段。第三阶段(第 15.12.2.4 节)允许重载与可变数量方法、装箱和拆箱相结合。因此,从上述步骤中可以清楚地看出,在您的情况下,在第一阶段, Java 编译器将找到一个匹配的方法,该方法可以执行doCalc(long a,long b). 您的方法doCalc(Byte s1, Byte s2)在调用期间需要自动装箱,因此它的优先级会降低。

白衣非少年

在您的情况下发生的情况是,在运行时,JVM 选择执行扩大转换 byte -> long,因为这种转换更安全,因为可以保证它不会导致RuntimeException.从 转换为byte也Byte称为装箱可能会导致OutOfMemoryError,因为 JVM 必须将新对象分配到堆上:如果需要分配包装类(Boolean、Byte、Character、Short、Integer、Long、Float 或 Double)之一的新实例并且可用存储空间不足,则装箱转换可能会导致 OutOfMemoryError。因此,首选更安全的byte -> long 加宽转换。

开满天机

为了找到正确的过载,顺序是:按参数数量装箱/拆箱可变参数所以如果b结果Byte是Byte, Byte.如果通过的话,new byte[] { b, b }结果就是byte, byte。如果传递两个字节 b,则可以从 byte扩展到 int 到 long,结果为long, long。当长长的超载被移除时,Byte, Byte就会产生结果。
随时随地看视频慕课网APP

相关分类

Java
我要回答