varargs and the '...' argument
Asked Answered
O

3

47

Consider the method declaration:

String.format(String, Object ...)

The Object ... argument is just a reference to an array of Objects. Is there a way to use this method with a reference to an actual Object array? If I pass in an Object array to the ... argument - will the resultant argument value be a two-dimensional array - because an Object[] is itself an Object:

Object[] params = ....; // Make the array (for example based on user-input)
String s = String.format("%S has %.2f euros", params);

So the first component of the array (Which is used in the String.format method), will be an array and he will generate:

[class.getName() + "@" + Integer.toHexString(hashCode())] 

and then an error because the array size is 1.

The bold sequence is the real question.
This is a second question: Does a ... array/parameter have a name?

Orsay answered 1/11, 2009 at 11:11 Comment(1)
Sorry, I had to test it before asking... I think I had this problem a long time ago.Orsay
P
54

From the docs on varargs:

The three periods after the final parameter's type indicate that the final argument may be passed as an array or as a sequence of arguments.

So you can pass multiple arguments or an array.

The following works just fine:

class VarargTest {
  public static void main(String[] args) {
    Object[] params = {"x", 1.2345f};
    String s = String.format("%s is %.2f", params);
    System.out.println(s); // Output is: x is 1.23
  }
}
Paulie answered 1/11, 2009 at 11:20 Comment(3)
So if you want to call the method with a single argument and it happens to be an array, you have to explicitly wrap it in another. method(new Object[]{array});Segalman
or do method((Object)array), which will auto-wrapJessen
I'm better off than before I saw these explanations about vararg parameters, yet I still just don't get it.Archiearchiepiscopacy
S
11

You can just pass an array:

public void foo(String... args) {
}

String args[] = new String[10];
foo(args);
Salsbury answered 1/11, 2009 at 11:16 Comment(1)
I'm not going to even bother adding my own answer, edit in "... is known as vararg or variable arguments and requires 0..n elements of specified elements" or something like that.Demo
F
7

The situation you are describing is going to be fairly rare: most of the time, your varargs items will be Strings, or numbers, or Widgets... it will be unusual for them to be Objects (which could be anything) or arrays.

But if the varargs argument is a bunch of Objects or an array type, then your question does arise: you can pass it a single array and then how will the compiler know whether you meant to pass an array (the one you provided), or an series of 1 item which it should PUT into an array for you?

A quick test shows the answer:

public class TestClass {
    public static void main(String[] args) {
        Object anObject = new Object();
        Object[] anArray = new Object[] {anObject, anObject};
        System.out.println("object1 = " + anObject);
        System.out.println("array1 = " + anArray);
        takesArgs();
        takesArgs(anObject, anObject);
        takesArgs(anArray); // is this the same as array1?
        takesArgs(anArray, anArray);
    }

    public static void takesArgs(Object... stuff) {
        System.out.println("The array was " + stuff);
    }
}

The result of executing (your exact numbers will vary:

object1 = java.lang.Object@3e25a5
array1 = [Ljava.lang.Object;@19821f
The array was [Ljava.lang.Object;@addbf1
The array was [Ljava.lang.Object;@42e816
The array was [Ljava.lang.Object;@19821f
The array was [Ljava.lang.Object;@9304b1

So the answer is that in ambiguous cases it treats what you passed as the array instead of creating a new array to wrap it. This makes sense as you could always wrap it in an array yourself if you wanted the other interpretation.

Footrope answered 3/11, 2009 at 1:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.