views:

632

answers:

3

Hello,

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 (Who is used in the String.format method), will be an array and he will generate:

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

and then an error because the array size is 1.

I hope I have explained well. Maybe much grammar faults (14 years old and Dutch speaking), so forgive me.

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

+4  A: 

You can just pass an array:

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

String args[] = new String[10];
foo(args);
cletus
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.
Esko
+7  A: 

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
  }
}
Ayman Hourieh
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});`
Bart van Heukelom
+1  A: 

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.

mcherm