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.

Reply via email to