Archive for November 7th, 2007

A Syntax Trick I Was Not Aware Of

Suppose you have an incredibly powerful Gadget class:

// Example 1
public class Gadget {
  public void doSomething(List<String> things) {
    for (String thing : things) {
      System.out.println(thing);
    }
  }
}

Now, somewhere else, you decide to use Gadget as follows:

// Example 2
Gadget g = new Gadget();
g.doSomething(Arrays.asList("Red", "Green", "Blue"));

Cool, no problem. You can also do this:

// Example 3
List<String> stringList = Collections.emptyList();
g.doSomething(stringList);

It’s all good. But wait…that last snippet can be inlined, right? Sorry, but this will not compile:

// Example 4
// won't compile
g.doSomething(Collections.emptyList());

I think that after compiling the Gadget class, we lose some type information about List<String> things due to erasure. (although whenever I blog about generics or erasure, someone corrects my misguided theory in the comments…)

Fortunately, this syntax makes it work:

// Example 5
g.doSomething(Collections.<String>emptyList());

I think I encountered code like that a long time ago and then forgot about. Last week I wasn’t able to get something very similar to work, so I split my code into two separate lines as shown in Example 3. That worked, but I was not happy about it.

Then earlier this week I was helping a coworker, and I noticed he used the syntax shown in Example 5. I think my reaction was something like:

WTF is that?

Which led me to research the syntax in the JLS, which led me to the JLS documentation bug mentioned in my previous post.

Now I find myself wondering what other syntax I do not yet fully grasp?

Java Language Specification Bug

Just to be clear, this is a documentation bug in the JLS, not a bug in the language. Check out this example from Section 4.11 of the Java Language Specification:

void <S> loop(S s) {
  this.<S>loop(s);
}

That won’t compile for me. I have to put the <S> before the void, like this:

<S> void loop(S s) {
  this.<S>loop(s);
}

Simplify the Code

Now that the bug is fixed, IDEA warns that the second <S> is not required. “this.” is also extra noise, so you could simplify the recursive loop to this:

<S> void loop(S s) {
  loop(s);
}

Although I think they may have wanted the explicit <S> in there just to show the syntax.

Good luck running this example. :-)

See my next post for the reason why I ran across this little gem…