繁体   English   中英

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

[英]Method overloading : Single parameter vs alternating parameters

这个问题可能类似于Java过载混淆

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

我的问题是为什么编译器能够解析如果我的参数只有一个将调用哪个方法

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

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

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的隐式转换。

因此,当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..
}

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

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

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

因此发生编译错误。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM