Java неоднозначного типа для метода? - PullRequest
3 голосов
/ 23 октября 2009

РЕДАКТИРОВАТЬ: Это оказалось не проблема с кодом вообще, но с ошибкой в ​​плагине Groovy Eclipse (http://jira.codehaus.org/browse/GRECLIPSE-373)

Eclipse дает мне странное сообщение об ошибке о неоднозначных типах в Java-программе, и я действительно не понимаю, почему. У меня есть интерфейс, который принимает универсальный параметр, указывающий, какой тип данных он возвращает.

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

Одна из реализаций выглядит так:

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

Существует также контейнер для интерфейса A

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

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

    public T getA() {
        return a;
    }
}

Это приводит к ошибке «getData is ambiguous».

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

Я поставлен в тупик на этом.

Ответы [ 6 ]

5 голосов
/ 23 октября 2009

Кажется, есть ошибка, вызывающая это из плагина groovy. http://jira.codehaus.org/browse/GRECLIPSE-373. Это не проблема Java вообще. Спасибо за помощь и мои извинения.

2 голосов
/ 23 октября 2009

Collection<T> getData(), определенный в Impl, необходимо сделать общедоступным . Если я делаю это, код компилируется для меня чисто.

0 голосов
/ 23 октября 2009

Как говорили другие авторы, я не вижу этой проблемы в Eclipse 3.5.0, работающем на JDK 1.6.0.14 (при исправлении ограниченной видимости метода getData()).

Я предлагаю сделать чистую сборку (Project / Clean в Eclipse). Также может помочь версия Eclipse и Java, которую вы используете.

- Flaviu Cipcigan

0 голосов
/ 23 октября 2009

[Изменить, чтобы отразить обновленный вопрос]

Это даже не должно компилироваться, так как вы уменьшаете видимость метода из общего доступа в область действия пакета:

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

И это все еще компилирует для меня (Eclispe 3.4, OS X, 1.5), поэтому не знаю, в чем именно проблема:

пакет 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();
        }
    }
}
0 голосов
/ 23 октября 2009

То, что у вас здесь есть, кажется законным. Возможно, Eclipse показывает ошибку, которой не должно быть.

Перейдите в Windows> «Настройки»> «Java»> «Компилятор»> «Ошибки / предупреждения». В разделе «Общие типы» убедитесь, что Eclipse не сообщает об ошибке ни для одной из перечисленных операций (если только вы этого не хотите). У меня все в этом разделе установлено в «Предупреждение». Затем я попытался бы обновить проект и перезапустить Eclipse.

Edit: После того, как было сделано обновленное сообщение, я получил предупреждение (но не об ошибке) о том, как он используется: «Контейнер необработанный тип. Ссылки на универсальный тип Контейнер должны быть параметризованы:» Это может быть исправлено:

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

(В моем примере я использую java.util.Date вместо «AnotherClass»).

0 голосов
/ 23 октября 2009

Ваш отредактированный пример отлично работает для меня (JDK 1.5) за исключением того, что вы должны определить универсальный тип в конструкторе. Вот мой полный рабочий код:

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();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...