使用基元及其包装器重载方法

2022-09-03 07:07:22

我正在尝试制定在以下方案中使用的规则。请解释为什么我得到2个不同的输出。

方案 1 输出:我是对象。

class Test {

    public static void main (String[] args) {

        Test t = new Test(); 
        byte b_var = 10;
        t.do_the_test(b_var);
    }

    public void do_the_test(Character c) {

       System.out.println("I am a character.");
    }

    public void do_the_test(Integer i) {

      System.out.println("I am an integer.");
    }

    public void do_the_test(Object obj) {

      System.out.println("I am an object.");
    }
}

方案 2 输出:我是一个整数。

class Test {

    public static void main (String[] args) {

        Test t = new Test(); 
        byte b_var = 10;
        t.do_the_test(b_var);
    }

    public void do_the_test(char c) {

       System.out.println("I am a character.");
    }

    public void do_the_test(int i) {

      System.out.println("I am an integer.");
    }

    public void do_the_test(Object obj) {

      System.out.println("I am an object.");
    }
}

答案 1

Java语言规范对方法签名解析是这样说的:

第一阶段 (§15.12.2.2) 执行重载解析,不允许装箱或取消装箱转换,也不允许使用可变 arity 方法调用。如果在此阶段找不到适用的方法,则处理将继续到第二阶段。

在第二种情况下,涉及的方法签名在不自动装箱的情况下适用,但具有加宽的数字转换。在第一种情况下,需要加宽转换自动装箱才能达到签名;但是,Java要么进行自动装箱,要么进行原始转换,但绝不会两者兼而有之。intInteger


答案 2

选择方法时,将选择与传递的参数最接近的参数。

在第一种情况下,数字值可以选择三个类,它不能直接映射。由于 Object 是所有类的超级父,因此它与 fn[Object] 匹配,因此我是一个对象。

在第二种情况下,函数调用找到了与fn[integer]最接近的匹配函数,结果是我是整数。