Oliver Gierke Archive About Tags

JavaC issues implementing generics

15 December 2008

Attenting Devoxx last week, I had the chance to talk to Joshua Bloch about an compiler issue I had a while ago implementing static factory method pattern from his book. Take this as example:

public class PluginRegistry <T extends Plugin<S>, S> {
  public static <T extends Plugin<S>, S>
    PluginRegistry<T, S> create() {
    return new PluginRegistry();
  }
}

PluginRegistry<Plugin<String>, String> registry =
  PluginRegistry.create();

Don’t try to get the details, there are only three important things:

The strange thing is, this compiles within Eclipse but does not on plain javac. I mailed Alex Buckley about the issue and after some back and forth he discovered a strange issue with javac.

To let the cat out of the bag: its a bug in javac. Actually according to Maurizio Cimadamore it is a coeffect of some bugs that are actually already marked as fixed (6192945, 6369605, 6193815). I’ll leave out the bloody details, here is, what it boils down to:

Javac somehow only tries to lookup types forward in this case. It infers T == Plugin<String>, but complains that for it Plugin<String> is not a subtype of Plugin<S> (as it has not inferred S yet). Guess what, if you simply switch the generic parameters, it compiles like a charm:

public class PluginRegistry <T extends Plugin<S>, S> {
  public static <S, T extends Plugin<S>>
    PluginRegistry<T, S> create() {
    return new PluginRegistry();
  }
}

PluginRegistry<Plugin<String>, String> registry =
  PluginRegistry.create();

(Note the order of the generic types in the method signature)

Tell me if it’s just me, but now the method signature somehow looks “wrong” to me. As the types are not being derived in the order they are declared at the method. Nevertheless, I at least compiles both on javac and the Eclipse compiler. So keep an eye on stuff like this, if you implement generic types ;). I’ll give you an update if there are further things happen on this.

blog comments powered by Disqus
Fork me on GitHub