简体   繁体   中英

Method overloading - reference to is ambiguous

I'm trying to get better grips of function overloading.

I've this test program (pardon me for my C inspired Java).

public class Test {
    static void f(int x, double y)
    {
        System.out.printf("%d, %f",x,y);
    }

    static void f(double x, int y)
    {
        System.out.printf("%f, %d", x, y);
    }


    public static void main(String args[]) {

    f(1, 2);

    }
}

now if I call,

f(1, 2);

There is compiler error, *reference to f is ambiguous*

Why this error? Are we not calling f(int, int) ? But no such method is declared. I was expecting "no suitable method found for f" instead, but I did not get one, why?

int is convertible to double in all of these languages, so if only one of them were available, it would be easy: convert whichever value needs to be converted to a double , and call the method.

But in this case, both methods are "valid" in that each would be fine on its own - but neither is "better" than the other, because in each case one argument only needs the identity int to int conversion, and the other needs the int to double conversion. So in both Java and C# it's ambiguous and will fail with a compile-time error. I'd imagine that's what it does in C++ too, but I don't know for sure. In both Java and C#, if you had also a method static void f(int x, int y) , that would unambiguously be better than either of the other two, for that method invocation.

When in doubt, you should consult the relevant language specifications. For Java, JLS section 15.12 is the relevant part. In the C# 5 specification , it's section 7.5.

you have these functions that are awfully close to each other or better sense ambiguous for the compiler to understand so compilers gets confused to see these

static void f(int x, double y)

static void f(double x, int y)

In order to get rid of this confusion or ambiguity for the compiler simple add following

 static void f(int x, int y)

I think this comment explain it better for you

The problem is not the lack of a method that has two int parameters. The problem is that there are two methods that are equally good matches according to Java's rules for matching method calls to methods. Eliminate one of the existing f() methods and the error will go away. Ted Hopp

In f(1, 2); both numbers can be interpreted as either int or double , so it's ambiguous. You can clarify by writing like this:

f(1., 2);

or

f(1d, 2);

However, it's not a good practice to overload a method with multiple signatures that have the same number of parameters. It's a good practice to avoid such overloadings as much as possible.

A classic example of how things can go wrong with overloading with same number of parameters, from Joshua Bloch's Effective Java:

public class CollectionClassifier {
   public static String classify(Set<?> s) {
       return "Set";
   }
   public static String classify(Collection<?> c) {
       return "Unknown Collection";
   }
   public static void main(String[] args) {
       Collection<?>[] collections = {
           new HashSet<String>(),
           new ArrayList<BigInteger>()
       };
       for (Collection<?> c : collections) {
           System.out.println(classify(c));
       }
   }
}

This will print Unknown Collection twice, and it can be easy to overlook.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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