Tiger adds all sorts of automatic conversions and conveniences, which is pretty cool...about 99% of the time. Unfortunately, there are times when all those helps turn into hindrances. The conversion of Object... to Object[] in a varargs method can be one of those cases, and you'll find that in rare cases, you need to work around Java.
Before getting into the details of getting around this issue, be sure you understand the problem. Take Java's new printf( ) method, a real convenience:
System.out.printf("The balance of %s's account is $%(,6.2f\n", account.getOwner().getFullName( ), account.getBalance( ));
If you look at the Javadoc for printf( ), you'll see its a varargs method, with two parameters: a String for the formatting string, and then Object... for all the arguments passed in for use in that formatting string:
PrintStream printf(String format, Object... args)
NOTE
printf( ), along with the other new Tiger formatting methods, are detailed in Chapter 9.
By now, you can mentally convert this to the following:
PrintStream printf(String format, Object[] args)
All good, right? Well, most of the time. Consider the following code:
Object[] objectArray = getObjectArrayFromSomewhereElse( ); out.printf("Description of object array: %s\n", obj);
NOTE
I realize this isn't the most common scenario. Then again, if all I covered were common scenarios, we'd all be debugging right now, wouldn't we?
This might seem a bit far-fetchedhowever, consider this as normal fare for introspective code. That's a ten-cent word for code that investigates other code. If you are writing a code analysis tool, or an IDE, or anything else that might use reflection or a similar API to figure out what objects an application uses, this suddenly becomes a normal usecase. Here, you're not really interested in the contents of the object array as much as you are with the array itself. What type is it? What's its memory address? What is its String representation? Keep in mind that all these questions apply to the array itself, and not to the contents of the array. For example, let's say the array is something like this:
public Object[] getObjectArrayFromSomewhereElse( ) { return new String[] {"Hello", "to", "all", "of", "you"}; }
In that case, you might write some code like this to begin to answer some questions about this array:
out.printf("Description of object array: %s\n", obj);
However, the output isn't what you expect:
run-ch05: [echo] Running Chapter 5 examples from Java Tiger: A Developer's Notebook [echo] Running VarargsTester... [java] Hello
What in the world? This is hardly what you'd expect to seehowever, the compiler did just what it always didit converted Object... in the printf( ) method to Object[]. When it read your method invocation, it saw an argument that was, in fact, Object[]! So instead of treating the array as an object itself, it broke it up into its various parts. The first argument became the String "Hello", which was passed to the format string (%s), and the result was "Hello" being printed out.
To get around this, you need to tell the compiler that you want the entire object array, obj, treated as a single object, and not as a grouping of arguments. Here's the magic bullet:
out.printf("Description of object array: %s\n", new Object[] { obj });
Alternatively, here's an even shorter approach:
out.printf("Description of object array: %s\n", (Object)obj);
In both cases, the compiler no longer sees an array of objects, it simply sees a single Object (which just happens to be an array of objects). The result is what you should want (at least in this rather odd scenario):
run-ch05: [echo] Running Chapter 5 examples from Java Tiger: A Developer's Notebook [echo] Running VarargsTester... [java] [Ljava.lang.String;@c44b88
While this may look like gibberish to you, it's probably what reflection-based or other introspective code wants to take a look at.