Why does this code compile?
Hello,
Can someone please tell me why this code compiles? I thought it must give an error because of an ambiguous call to varargs(), but it prints "Hello1" when varargs(1 ) is called.
Code java:
package test;
public class Test {
public static void varargs(int x, int ...v) {
System.out.println("Hello2");
}
public static void varargs(int x) {
System.out.println("Hello1");
}
/**
*
* @param x
* @param y
*/
public static void main(String[] args) {
System.out.println("Main method");
varargs(1);
}
}
Re: Why does this code compile?
The program compiles and will print out "Hello1" since you called the method, varargs, that accepts a single int as a parameter. Everything seems to be fine.
Re: Why does this code compile?
How does the program distinguish which method to call? Since both methods take 1 int, I could be calling either of them (because varargs can take no arguments also).
Re: Why does this code compile?
The place to go for an answer to questions like this is the Java Language Specification. In this case the relevant part is 15.12 Method Invocation Expressions (chapter 15 deals with the meaning of all the different sorts of expression that can arise in Java).
Be warned, the specification aims at being comprehensive and definitive not at being readily comprehensible! When it comes to this particular question, 15.12 begins with the observation that "Resolving a method name at compile time is more complicated than resolving a field name because of the possibility of method overloading. Invoking a method at run-time is also more complicated than accessing a field because of the possibility of instance method overriding". So for someone starting out the thing to understand is that the non varargs form will be preferred if there is a choice: that's just how Java is. So there is no ambiguity. And no problem with compilation.
---
The messy details are spelt out in 15.12, which shows how varargs takes its place alongside all the other things that have to be determined as the compiler attempts to compile both forms of the varargs() method, or as the runtime evaluates expressions involving that method. In particular the first step of 15.12.2 Compile-Time Step 2: Determine Method Signature says "The first phase (§15.12.2.2) performs overload resolution without permitting boxing or unboxing conversion, or the use of variable arity method invocation. If no applicable method is found during this phase then processing continues to the second phase".
In other words variable arity methods are only considered for an expression like "varargs()" is there is no match with a no argument form. There is a note following this statement giving a rationale in terms of being compatible with old code (calling the method) from before Java 5, if the varargs form is added later.
Re: Why does this code compile?
Re: Why does this code compile?