1

Usually methods with a fixed number of arguments are preferred over overloaded methods with a variable number of arguments. However, this example behaves differently:

public class Main{
 public static void main(String[] args){
  print(1);
  print(1,2);
  print(new String[]{"a","b"});
  print(new String[][]{{"a","b"},{"c","d"}});
 }

 public static void print(Object object){
  System.out.println("single argument method");
  System.out.println(object);
 }

 public static void print(Object object0,Object object1){
  System.out.println("two argument method");
  System.out.println(object0);
  System.out.println(object1);
 }

 public static void print(Object... objects){
  System.out.println("varargs method with "+objects.length+" arguments");
  for(Object object : objects){
   System.out.println(object);
  }
 }
}

Output:

single argument method
1
two argument method
1
2
varargs method with 2 arguments
a
b
varargs method with 2 arguments
[Ljava.lang.String;@5e2de80c
[Ljava.lang.String;@1d44bcfa

The third line of main calls the method with one argument, which is a String[] with two elements. But that doesn't execute the method with one argument, but instead executes the varargs method and acts like I gave it two arguments (which is sort of normal, since it's an array).

Now the question: Should this happen? Have I found a bug or undocumented behaviour? Is there a reason why it does this?

Why I'm doing this: I want to make a shortcut for printing to console which can both take in an arbitrary number of arguments (for multiple lines) and also print arrays and lists in a nice way.

Fabian Röling
  • 1,227
  • 1
  • 10
  • 28

1 Answers1

2

Should this happen?

Yes

Have I found a bug or undocumented behaviour?

No

Is there a reason why it does this?

Yes. From Oracle:

It is still true that multiple arguments must be passed in an array, but the varargs feature automates and hides the process. Furthermore, it is upward compatible with preexisting APIs.

When you use an array explicitly it still matches the varargs signature. It was done so so that people could easily switch an array parameter to varargs without breaking existing integration points.

It's exactly the same reason that main can be String[] or String...

Michael
  • 41,989
  • 11
  • 82
  • 128
  • But it also matches the signature of the method with one argument. So why isn't that one called? – Fabian Röling Dec 13 '18 at 14:04
  • Because the varargs one is more specific and the most specific method is always the one which is chosen. Given your use case, you don't really need the single argument method in addition to varargs. – Michael Dec 13 '18 at 14:08
  • No, as you can see, it chooses the single argument method for `print(1)` and the two argument method for `print(1,2)` instead of the varargs method. And just by logic, they are more specific: They specify the number of arguments and they are applicable for less cases. – Fabian Röling Dec 13 '18 at 14:40