user218046
user218046

Reputation: 633

Java varargs method overloading compiler error - ambiguity?

So, today I've been testing Java's overloading techniques and I've come across ambiguity which I can't explain. Basically, when there is a vararg method with primitive and its corresponding wrapper the compiler complains and can't decide which one to choose and I don't understand why? It's easy for human to decide and not for compiler?

Here is the fragment which works for non-vararg parameters:

public static void main(String[] args)
{
    int a = 14;
    Integer b = new Integer(14);
    stuff(a);
    stuff(b);
}

static void stuff(Integer arg) { System.out.println("Integer"); }
static void stuff(int arg) { System.out.println("int"); }

And here comes the vararg which complains and cries like a baby:

public static void main(String[] args)
{
    int a = 14;
    Integer b = new Integer(14);
    stuff(a); // Doesn't compile (ambiguity)
    stuff(b); // Doesn't compile (ambiguity)
}

static void stuff(int... arg) { System.out.println("varargs int"); }
static void stuff(Integer... arg) { System.out.println("varargs Integer"); }

Upvotes: 1

Views: 779

Answers (2)

Tim Biegeleisen
Tim Biegeleisen

Reputation: 521457

Consider the following two hypothetical calls to stuff():

int a = 14;
Integer b = new Integer(14);

stuff(a, b);
stuff(b, a);

How does the compiler even know which method should be called here? Because of autoboxing rules, either call could be referring to either overloaded method.

Update:

My answer is logically correct, or at least on the right track, but for a more formal answer we can refer to this SO question:

Why ambiguous error when using varargs overloading with primitive type and wrapper class?

The two varargs method are invoked in loose invocation context. As a result, the compiler will attempt to find the more specific method via JLS 15.12.2.5 Choosing the Most Specific Method. However, since neither int nor Integer are subtypes of one another, the compiler will throw an error.

Upvotes: 3

The problem is:

java is doing behind the scenes bridge methods (you need to verify that is you need deep info)

AND the important part, vargargs means too YOU CAN JUST NOT PASS ANY PARAMETER, so:

static void stuff(int... arg)   

and

static void stuff(Integer... arg) 

can both being invoked taking no parameters... so that will create some conflict about what method should the JVM invoke

Upvotes: 3

Related Questions