简体   繁体   English

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

[英]Method overloading : Single parameter vs alternating parameters

This question might be similar to Java overload confusion 这个问题可能类似于Java过载混淆

I'm reading a book and there's a topic regarding method overloading from which a compiler may not be able to resolve the method being called. 我正在读一本书,并且有一个关于方法重载的主题,编译器可能无法解析被调用的方法。 The example on the book uses overloaded method with two parameters (int, double) and (double, int) . 本书中的示例使用带有两个参数(int, double)(double, int)重载方法。 Calling this method like overloadedTwoParam(4, 5) will cause a compiler error because int can be passed to double. 像overloadedTwoParam(4,5)一样调用此方法将导致编译器错误,因为int可以传递给double。 My question here is why compiler able to resolve which method will be called if my parameter is only one ? 我的问题是,为什么编译器能够解析如果我的参数只有一个,将调用哪个方法?

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..
    }
}

My question here is why compiler able to resolve which method will be called if my parameter is only one 我的问题是为什么编译器能够解析如果我的参数只有一个将调用哪个方法

When it comes to a single parameter, the compiler is able to see that there is a method that takes an int so there is no confusion about which method should be called. 当涉及单个参数时,编译器能够看到有一个方法接受一个int因此不应该混淆应该调用哪个方法。 Even if you delete the method that takes a single int , the compiler will still be able to call the method that takes a single double since there is no ambiguity here. 即使您删除了采用单个int的方法,编译器仍然可以调用采用单个double的方法,因为这里没有歧义。 ( int can be promoted to a double ) int可以提升为double

When it comes to the other methods that alternate the int and double parameters, the compiler does not want to take responsibility for deciding whether to promote the first parameter to a double or the second parameter to a double . 当涉及交替intdouble参数的其他方法时,编译器不想负责决定是将第一个参数提升为double还是将第二个参数提升为double

The CKing intuition and answer is good. CKing的直觉和答案很好。
I will complete with JLS reference. 我将完成JLS参考。

The general idea is : the compiler chooses the most specific method ... if it founds it . 一般的想法是: 编译器选择最具体的方法......如果它找到了它

The JLS states that the informal intuition is that one method is more specific than another if any invocation handled by the first method could be passed on to the other one without a compile-time type error. JLS声明非正式的直觉是,如果第一个方法处理的任何调用都可以传递给另一个没有编译时类型错误的调用,那么一个方法比另一个方法更具体。 It is the short version. 这是简短的版本。
In the JLS link referenced, all rules applied by the compiler to choose the most specific method are specified. 在引用的JLS链接中,指定了编译器应用于选择最具体方法的所有规则。

It is possible that no method is the most specific, because there are two or more methods that are maximally specific. 可能没有方法是最具体的,因为有两种或更多种方法是最具体的。 In this case a compilation error occurs specifying that the method invocation is ambiguous. 在这种情况下,会发生编译错误,指定方法调用不明确。


In the first scenario the compilation is fine as you have a unique maximally specific method : 在第一个场景中,编译很好,因为您有一个独特的最大特定方法:

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) is an exact matching as we have both int as formal parameter of the method and effective parameter. void overloadedSingleParam(int a)是一个精确匹配,因为我们将int作为方法的形式参数和有效参数。
While overloadedSingleParam(double a) requires an implicit conversion from int to double . 虽然overloadedSingleParam(double a)需要从intdouble的隐式转换。

So overloadedSingleParam(double a) is less specific than void overloadedSingleParam(int a) when an int value is passed as argument. 因此,当int值作为参数传递时, overloadedSingleParam(double a)的特性不如void overloadedSingleParam(int a)
So the compiler chooses void overloadedSingleParam(int a) and the compilation is successful. 所以编译器选择void overloadedSingleParam(int a)并且编译成功。


In the second scenario, things are different : you fall in the case of no one method is more specific than another one : 在第二种情况中,情况有所不同:在没有一种方法比另一种方法更具体的情况下,你会陷入困境:

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..
}

You can check it with the informal intuition : 你可以用非正式的直觉来检查它:

  • overloadedTwoParam((double)3, 4) applied to void overloadedTwoParam(int a, double b) doesn't compile. overloadedTwoParam((double)3, 4)应用于void overloadedTwoParam(int a, double b)不编译。

  • overloadedTwoParam(3, (double)4) applied to void overloadedTwoParam(double a, int b) doesn't compile either. overloadedTwoParam(3, (double)4)应用于void overloadedTwoParam(double a, int b)也不编译。

Consequently a compilation error occurs. 因此发生编译错误。

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

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