When all else fails, check the documentation

April 09, 2011

I ran into a bug in my code today because I didn’t implement clone in a class that needed it (it’s used for rescheduling a failed task). Naturally, I went to fix the code to make these errors impossible through the magic of Type Safety, but Java wasn’t playing fair. It turns out this doesn’t compile:

void breathe(Class<? extends Mammal & Marine> swimmer) {
    // ...
  }

This very similar method works fine:

<T extends Mammal & Marine> void breathe(Class<T> swimmer) {
    // ...
  }

This seemed like some strange bug. I was in the midst of writing the buzzword-iest question ever posted to Stack Overflow (“Are wildcard generic type parameters extending intersection types allowed in Java?”) when I realized the authoritative source is readily available. According to the Java Language Specification section 4.4, a type parameter can have an AdditionalBoundList. But according to section 4.5.1, a wildcard type argument only gets to refer to a single ReferenceType.

The Java Language Specification isn’t a great tutorial or guide to best practices, but it is the definitive answer to some questions. It still doesn’t explain why. I’m not sure there is a technical reason it couldn’t be done or if it was accidental. I suspect it may just be that no one thought to add multiple bounds to the wildcard spec.