The Source for Java Technology Collaboration
User: Password:



Richard Bair

Richard Bair's Blog

Varargs Puzzler

Posted by rbair on August 10, 2006 at 02:28 PM | Comments (10)

This probably isn't up to Click 'n' Hack's standards, but here's a fun little Java 5 puzzler for a Thursday afternoon.

NOTE: For those in the dark, Click and Hack are really Neal Gafter and Joshua Bloch. They have a little skit they do at conferences where they present java code puzzlers.

Alright, we've had Java 5 for a while now and have had a good chance to get up to date with our new language features. In this puzzler I've written a method that takes a vararg of Objects, counts them up, and returns how many elements there were. Here's the code:


   private static int elementCount(Object... elements) {
     return elements == null ? 0 : elements.length;
   }

   public static void main(String... args) {
     System.out.println("null length array: " + elementCount(null));
     System.out.println("[a,b,c] length array: " + elementCount("a", "b", "c"));
   }

Pretty straight to the point. I have a method called elementCount, and it simply returns the length of the elements array, or 0 if the param is null. So what's wrong with it?

  a) Nothing at all! It works as expected!
  b) There is a compiler warning
  c) It fails to compile
  d) Both (a) and (b)

Ok, I'll give you a few minutes to look it over, read the Java Language Specification, try it out in your favorite IDE, etc. Done?

And the answer is..... d! In fact, there is a compiler warning on this line:


    //line of code
    System.out.println("null length array: " + elementCount(null));

    //compiler warning
    warning: non-varargs call of varargs method with inexact argument type for last parameter;

Besides this warning, though, the code executes properly. But since I don't really like compiler warnings, I go ahead and make the change. Here's the new code.


   private static int elementCount(Object... elements) {
     return elements == null ? 0 : elements.length;
   }

   public static void main(String... args) {
     System.out.println("null length array: " + elementCount((Object)null));
     System.out.println("[a,b,c] length array: " + elementCount("a", "b", "c"));
   }

Alright, that took care of the warning! So what's wrong with it? Anything? Come on, no cheating, think about it!

  a) It runs, but prints out "[a,b,c] length array: 0"
  b) There is a compiler warning
  c) Perfecto!
  d) It runs, but prints out "null length array: 1"

Alright, you've had your chance. What is it?




That's right, "d" again. It turns out the problem is this statement: elementCount((Object)null). The problem is that (Object)null tells the compiler to include a one element Object array where the first element is null. Instead, what we wanted to do was this (Object[])null! This is why we get the compiler warning, the compiler doesn't know if we want null to be an element in the vararg array or whether we want it to be the vararg array itself.

Tripped me up for a few minutes today, hope you enjoyed it.

Note: Updated to refer to "Click and Hack" instead of "Click and Clack" -- also fixed a typo in the description. Thanks for pointing these things out!


Bookmark blog post: del.icio.us del.icio.us Digg Digg DZone DZone Furl Furl Reddit Reddit
Comments
Comments are listed in date ascending order (oldest first) | Post Comment

  • While Neal and Joshua may well do skits at conferences as "Click and Clack", presenting Java puzzlers, the heritage of those names goes back much further! Click and Clack are the on air names of the two guys who do NPR's (that's National Public Radio) Car Talk.

    And guess what? Each week they present a brain teaser which is referred to as the puzzler. These guys have been going since the late 70's, so I'm pretty sure they are the original Click and Clack on which Neal and Josh have based their skit.

    -Tim Fennell
    Stripes: Because web development should just be easier

    Posted by: tfenne on August 10, 2006 at 05:43 PM

  • Nice puzzler, but why not just write:

    System.out.println("null length array: " + elementCount());

    Which to me is much more logical :-)

    Posted by: quintesse on August 10, 2006 at 11:56 PM

  • @quintesse you are right; calling elementCount with no args is perfect for showing that the array of args will be empty

    @rbair elementCount(null) returns the same value as elementCount("a") but I think the compiler gives a warning in the first case just to make sure you are doing the thing you really want to do

    Posted by: jsarmis on August 11, 2006 at 12:13 AM

  • Actually, Neal and Josh go by "Click and Hack", not "Click and Clack", they aren't stealing the name, its more of a tribute.

    Posted by: heaththegreat on August 11, 2006 at 08:26 AM

  • I think you've got a slight typo. You say that "I have a method called elementCount, and it simply returns the length of the elements array, or null if there are no elements. "

    But look at elementCount:
    return elements == null ? 0 : elements.length;

    You're returning zero if there are no elements (or if it's null), not null.

    Posted by: jattardi on August 11, 2006 at 09:22 AM

  • Whoops, I forgot to use line breaks on my previous comment. Sorry about that!

    Posted by: jattardi on August 11, 2006 at 09:23 AM

  • quintesse: Sweet! I didn't even know that was valid. Thanks for posting!
    heaththegreat: You're right, my bad. I'll update the article.
    jattardi: You got me! I'll update the text. Thanks.

    Posted by: rbair on August 11, 2006 at 10:22 AM

  • Actually calling the method with no args isn't really what you might expect.

    elementCount() gets replaced by the compiler with this

    elementCount(new Object[])

    It creates an empty array each time. Personally I don't like that, as it creates a new array each method invocation.

    Decompile it and you'll see.

    Posted by: atehrani on August 11, 2006 at 11:28 AM

  • Actually it is up to Click and Hack's standards; we use a variant on this one in our latest talk "The Continuing Adventures of Java Puzzlers: Tiger Traps.":)

    Regards,

    Click and Hack, the Type-it Brothers

    Posted by: jbloch on August 12, 2006 at 04:44 PM

  • Nice post Richard.
    Thanks.

    Here's the multimedia and PDF for the JavaOne session where Josh and Neil discuss similar topics.

    Posted by: rationalpi on August 15, 2006 at 01:35 PM



Only logged in users may post comments. Login Here.


Powered by
Movable Type 3.01D
 Feed java.net RSS Feeds