Guys,
while preparing some exercises with generics (finalized in finding the
better way to design some stuff), I've run into a what it sounds as a
compiler bug. Well, there's the bug smell since the error message is
intermittent - sometimes the compiler fails, sometimes not. In any case,
the message is:
[ERROR]
/home/tomcat/Workspaces/Hudson/jobs/OpenBlueSky_Compile_from_Scratch/workspace/jdk/JDK_1.6.0_21/modules/Hierarchy/HierarchySimple/src/main/java/it/tidalwave/hierarchy/spi/simple/SimpleHViewManager.java:[52,4]
types
it.tidalwave.hierarchy.spi.simple.HFinderSupport<it.tidalwave.hierarchy.HView>
and
it.tidalwave.hierarchy.spi.simple.HFinderSupport<it.tidalwave.hierarchy.HView>
are incompatible; both define from(int), but with unrelated return types
Pretty cool, right? It's complaining about a class defining the return type of
a method in a different way than... itself. The problem is that there are two
implementation paths from which the method is found.
Let me first give you the relevant parts of the involved interfaces / classes
(some moderate generics tweaking, otherwise it wouldn't be an exercise!):
public abstract class FinderSupport<Type, ExtendedFinder extends FinderSupport<Type,
ExtendedFinder>> implements Finder<Type>
{
public ExtendedFinder from (final int firstResult)
}
public interface ExtendedFinderSupport<Type, ExtendedFinder extends Finder<Type>>
extends Finder<Type>
{
public ExtendedFinder from (int firstResult);
}
public interface Finder<Type>
{
public Finder<Type> from (int firstResult);
}
Now, let's see the hierarchy of the bugged class:
public abstract class HFinderSupport<T> extends FinderSupport<T, HFinderSupport<T>>
implements i.t.h.Finder<T>
{
// more methods
}
public interface i.t.hFinder<Type> extends ExtendedFinderSupport<Type,
i.t.h.Finder<Type>>
{
// more methods
}
class SimpleHViewManagerFinder extends HFinderSupport<HView> // I don't
think it's relevant, anyway this is an inner class
{
// ...
}
Let's look at how the return type for from() is inferred from the above
declarations:
HFinderSupport<HView> from HFinderSupport -> Finder
i.t.h.Finder<HView> from HFinderSupport -> i.t.h.Finder
Actually they are different return types, even though HFinderSupport implements
i.t.h.Finder and I supposed the compiler is able to resolve. Apparently it
can't.
But, indeed, a similar (but simpler) case works fine:
public interface PersonFinder extends ExtendedFinderSupport<Person,
PersonFinder>
{
// more methods
}
public class DefaultPersonFinder2 extends FinderSupport<Person,
DefaultPersonFinder2> implements PersonFinder
{
// more methods
}
The return type for from() is:
DefaultPersonFinder2 // from FinderSupport
PersonFinder // from PersonFinder
DefaultPersonFinder2 implements PersonFinder. In this case the compiler
doesn't complain.
Now the question is: is it my stuff formally correct and I've run into a
compiler bug? Technically, the former case is a bit more complex and
this explains why the "bug" doesn't get triggered. But conceptually the
problem is the same (having two paths for inferring the return type of a
method which give two types, one of which is the implementation of the
other). I'd like to understand whether this is formally correct or not.
Thanks.
--
Fabrizio Giudici - Java Architect, Project Manager
Tidalwave s.a.s. - "We make Java work. Everywhere."
java.net/blog/fabriziogiudici - www.tidalwave.it/people
[email protected]
--
You received this message because you are subscribed to the Google Groups "The Java
Posse" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/javaposse?hl=en.