Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overloading function using varargs

This will not compile:

public class Methods
{

    public static void method(Integer... i)
    {
        System.out.print("A");
    }

    public static void method(int... i)
    {
        System.out.print("B");
    }

    public static void main(String args[])
    {
        method(7);
    }
}

This will compile and work:

public class Methods
{

    public static void method(Integer i)
    {
        System.out.print("A");
    }

    public static void method(int i)
    {
        System.out.print("B");
    }

    public static void main(String args[])
    {
        method(7);
    }
}

First and second example are very similar. First uses varargs, second not. Why one works, second not. 7 is primitive, so second method should be called in both cases. Is it normal behaviour?

I found it: Bug report Stack overflow

like image 351
Pawel Avatar asked Dec 19 '13 22:12

Pawel


People also ask

Can a Varargs method be overloaded?

A method with variable length arguments(Varargs) can have zero or multiple arguments. Also, Varargs methods can be overloaded if required.

What is the rule for using varargs in Java?

While using the varargs, you must follow some rules otherwise program code won't compile. The rules are as follows: There can be only one variable argument in the method. Variable argument (varargs) must be the last argument.

Is it good to use varargs in Java?

Varargs are useful for any method that needs to deal with an indeterminate number of objects. One good example is String. format . The format string can accept any number of parameters, so you need a mechanism to pass in any number of objects.

How can overloading method be resolved?

The process of compiler trying to resolve the method call from given overloaded method definitions is called overload resolution. If the compiler can not find the exact match it looks for the closest match by using upcasts only (downcasts are never done). As expected the output is 10.


1 Answers

This is a high-level informal summary of what is going on.

Firstly varargs syntax is really just syntactic sugaring for passing an array. So method(7) is actually going to pass an array of ... something.

But an array of what? There are two options here corresponding to the two overloads of the method; i.e an int[] or a Integer[].

If there are two or more overloads that could work (i.e. right method names, right numbers of arguments, convertible values) then the resolution process will chose the overload that is an exact match over a match that requires conversions, and complain if the only candidates require conversions. (This is a drastic simplification of the rules ... see the JLS section 15.12 for the complete story ... and be prepared for a long / difficult read!)

So what is happening in your first example is that it is trying to decide between two methods that both require conversions; i.e. int to int[] versus int to Integer[]. Basically it cannot decide which alternative to use. Hence a compilation error that says that the call is ambiguous.

If you change the varargs call to a call passing an explicit Integer[] or int[], you now get an exact match to one of the two overloads ... and the rules above say that this is not ambiguous.


I understand it as: 7 is primitive so it should be converted to array - int[].

The problem is that 7 can also be converted to an Integer[] ... by auto-boxing the int first.

like image 113
Stephen C Avatar answered Sep 20 '22 06:09

Stephen C