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

时间:2017-02-05 08:50:49

标签: java overloading

此问题可能类似于Java overload confusion

我正在读一本书,并且有一个关于方法重载的主题,编译器可能无法解析被调用的方法。本书中的示例使用带有两个参数(int, double)(double, int)的重载方法。像overloadedTwoParam(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 个答案:

答案 0 :(得分:7)

  

我的问题是,如果我的参数只有一个

,编译器能够解析将调用哪个方法

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

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

答案 1 :(得分:2)

CKing的直觉和答案是好的。
我将完成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的隐式转换。

overloadedSingleParam(double a)值作为参数传递时,void overloadedSingleParam(int a)的具体性不如int
因此编译器选择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..
}

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

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

  • 应用于overloadedTwoParam(3, (double)4)
  • void overloadedTwoParam(double a, int b)也无法编译。

因此发生编译错误。