有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java方法重载:单参数与交替参数

这个问题可能类似于Java overload confusion

我正在读一本书,其中有一个关于方法重载的主题,编译器可能无法解析调用的方法。本书中的示例使用了重载方法,该方法有两个参数(int, double)(double, int)。像重载edtwParam(4,5)一样调用此方法将导致编译器错误,因为int可以传递给double。我在这里的问题是,为什么编译器能够解析如果我的参数只有一个,将调用哪个方法

public class Test {

    public static void main(String[] args) {
        Test t = new Test();
        t.overloadedSingleParam(1); //this is working
        t.overloadedTwoParam(4, 5); //this is NOT working
    }

    void overloadedSingleParam(double a) {
        // do something here..
    }

    void overloadedSingleParam(int a) {
        // do something here..
    }

    void overloadedTwoParam(double a, int b) {
        // do something here..
    }

    void overloadedTwoParam(int a, double b) {
        // do something here..
    }
}

共 (2) 个答案

  1. # 1 楼答案

    直觉和答案都很好
    我将完成JLS参考

    总体思路是:编译器选择最具体的方法。。。如果找到它

    JLS表示,非正式的直觉是,如果第一个方法处理的任何调用都可以传递给另一个方法,而不会出现编译时类型错误,那么一个方法比另一个方法更具体。 这是简短的版本
    在引用的JLS链接中,指定了编译器应用于选择最具体方法的所有规则

    可能没有一种方法是最具体的,因为有两种或两种以上的方法是最具体的。在这种情况下,会发生一个编译错误,指定方法调用不明确


    在第一个场景中,编译很好,因为您有一个独特的最大特定方法:

    Test t = new Test();
    t.overloadedSingleParam(1);
    
    ...
    void overloadedSingleParam(double a) {
        // do something here..
    }
    void overloadedSingleParam(int a) {
        // do something here..
    }
    

    void overloadedSingleParam(int a)是一个精确匹配,因为我们将int作为方法的形式参数和有效参数
    overloadedSingleParam(double a)需要从intdouble的隐式转换

    因此,当int值作为参数传递时,overloadedSingleParam(double a)不如void overloadedSingleParam(int a)具体
    因此编译器选择void overloadedSingleParam(int a),编译成功


    在第二种情况下,情况就不同了:如果没有一种方法比另一种方法更具体,那么您就会失败:

    Test t = new Test();
    t.overloadedTwoParam(4, 5);
    
    ...
    void overloadedTwoParam(double a, int b) {
        // do something here..
    }
    
    void overloadedTwoParam(int a, double b) {
        // do something here..
    }
    

    你可以用非正式的直觉来检查它:

    • 应用于void overloadedTwoParam(int a, double b)overloadedTwoParam((double)3, 4)未编译

    • 应用于void overloadedTwoParam(double a, int b)overloadedTwoParam(3, (double)4)也不会编译

    因此会发生编译错误

  2. # 2 楼答案

    My question here is why compiler able to resolve which method will be called if my parameter is only one

    当涉及到单个参数时,编译器能够看到有一个方法采用了int,因此不存在应该调用哪个方法的混淆。即使删除采用单个int的方法,编译器仍然能够调用采用单个double的方法,因为这里没有歧义。(int可以升级为double

    当涉及到替换intdouble参数的其他方法时,编译器不想负责决定是将第一个参数提升为double还是将第二个参数提升为double