为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

holdtom 2023-09-27 17:23:19
我从一些测验中获取了这段代码片段,使用 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)
查看完整描述

3 回答

?
萧十郎

TA贡献1815条经验 获得超13个赞

因此,如果您仔细阅读用于在编译时确定方法签名的 Java 语言规范,就会清楚:

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

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

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

因此,从上述步骤中可以清楚地看出,在您的情况下,在第一阶段, Java 编译器将找到一个匹配的方法,该方法可以执行doCalc(long a,long b). 您的方法doCalc(Byte s1, Byte s2)在调用期间需要自动装箱,因此它的优先级会降低。


查看完整回答
反对 回复 2023-09-27
?
白衣非少年

TA贡献1155条经验 获得超0个赞

在您的情况下发生的情况是,在运行时,JVM 选择执行扩大转换 byte -> long,因为这种转换更安全,因为可以保证它不会导致RuntimeException.

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

如果需要分配包装类(Boolean、Byte、Character、Short、Integer、Long、Float 或 Double)之一的新实例并且可用存储空间不足,则装箱转换可能会导致 OutOfMemoryError。

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


查看完整回答
反对 回复 2023-09-27
?
开满天机

TA贡献1786条经验 获得超13个赞

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

  1. 按参数数量

  2. 装箱/拆箱

  3. 可变参数

所以

  • 如果b结果ByteByte, Byte.

  • 如果通过的话,new byte[] { b, b }结果就是byte, byte

  • 如果传递两个字节 b,则可以从 byte扩展到 int 到 long,结果为long, long

  • 当长长的超载被移除时,Byte, Byte就会产生结果。


查看完整回答
反对 回复 2023-09-27
  • 3 回答
  • 0 关注
  • 111 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信