Question

EDIT: This turned out not be a problem with the code at all, but with a bug in the Groovy Eclipse plugin (http://jira.codehaus.org/browse/GRECLIPSE-373)

Eclipse is giving me a weird error message about ambiguous types in a Java program and I really don't understand why. I have an interface that takes a generic parameter indicating what type of data it returns.

public interface InterfaceA<T> {
    T getData();
}

One of the implementations of it looks like this:

public class Impl<T extends AnotherClass> implements InterfaceA<Collection<T>> {
    public Collection<T> getData() {
       // get the data
    }
}

There is also a container for an InterfaceA

public class Container<T extends InterfaceA>
{
    private T a;

    public Container(T a) {
        this.a = a;
    }

    public T getA() {
        return a;
    }
}

Doing this causes the "getData is ambiguous" error.

Container<Impl<AnotherClass>> c = new Container(new Impl<AnotherClass>());
Collection<AnotherClass> coll = c.getA().getData();

I'm stumped on this one.

Was it helpful?

Solution

There appears to be a bug causing this from the groovy plugin. http://jira.codehaus.org/browse/GRECLIPSE-373. It is not a java problem at all. Thanks for the help and my apologies.

OTHER TIPS

Collection<T> getData() defined in Impl needs to be made public. If I do this the code compiles cleanly for me.

As other posters have said, I am not seeing this problem on Eclipse 3.5.0 running on JDK 1.6.0.14 (when fixing the reduced visibility of the getData() method).

I suggest doing a clean build (Project/Clean in Eclipse). Also, the Eclipse and Java version you are running might help.

-- Flaviu Cipcigan

Your edited example works fine for me (JDK 1.5) with the exception, that you have to define the generic type on the constructor. Here is my complete working code:

public interface InterfaceA<T> {
    T getData();
}

public static class Impl<T extends Date> implements InterfaceA<Collection<T>> {
    public Collection<T> getData() {
        return null;
    }
}

public static class Container<T extends InterfaceA> {
    private T a;

    public Container(T a) {
        this.a = a;
    }

    public T getA() {
        return a;
    }

}

public static void main(String[] args) {
    Container<Impl<Date>> c = new Container<Impl<Date>>(new Impl<Date>());
    Collection<Date> coll = c.getA().getData();
}

[Edit to reflect updated question]

This shouldn't even compile as you are reducing the visibility of the method from public to package scope:

public class Impl<T extends AnotherClass> implements InterfaceA<Collection<T>> {
    Collection<T> getData() {
       // get the data
    }
}

And this still compiles for me (Eclispe 3.4, OS X, 1.5), so don't know what exactly is the issue:

package temp.tests;

import java.util.Collection;

public interface InterfaceA <T> {

    T getData();

    public static final class AnotherClass {}

    public static final class Impl<T extends AnotherClass> 
             implements InterfaceA<Collection<T>>
   {
        public Collection<T> getData () {
            return null;
        }
    }

    public static class Container<T extends InterfaceA>
    {
        private T a;
        public Container(T a) { this.a = a; }
        public T getA() { return a; }
    }

    public static final class Test {
        public static void main (String[] args) {
            Container<Impl<AnotherClass>> c = new Container(new Impl<AnotherClass>());
            Collection<AnotherClass> coll = c.getA().getData();
        }
    }
}

What you have here seems legitimate. Perhaps Eclipse is showing an error it otherwise should not.

Go to Windows > Preferences > Java > Compiler > Errors/Warnings. In the "Generic Types" section, ensure that Eclipse isn't reporting an error for any of the operations listed (unless you want it too). I have all mine in that section set to "Warning". I would then try refreshing the project and restarting Eclipse.

Edit: After the updated post was made, I got a warning (not an error still) on the lines of usage, saying "Container is a raw type. References to generic type Container should be parameterized:". This can be fixed by:

Container<Impl<Date>> c = new Container<Impl<Date>>(new Impl<Date>());

(In my example, I'm using java.util.Date as in place of 'AnotherClass').

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top