Java неоднозначный тип для метода?
-
06-07-2019 - |
Вопрос
Редактировать:Оказалось, что это проблема вовсе не с кодом, а с ошибкой в плагине Groovy Eclipse (http://jira.codehaus.org/browse/GRECLIPSE-373)
Затмение выдает мне странное сообщение об ошибке о неоднозначных типах в программе Java, и я действительно не понимаю, почему.У меня есть интерфейс, который принимает общий параметр, указывающий, какой тип данных он возвращает.
public interface InterfaceA<T> {
T getData();
}
Одна из его реализаций выглядит примерно так:
public class Impl<T extends AnotherClass> implements InterfaceA<Collection<T>> {
public Collection<T> getData() {
// get the data
}
}
Существует также контейнер для интерфейса.
public class Container<T extends InterfaceA>
{
private T a;
public Container(T a) {
this.a = a;
}
public T getA() {
return a;
}
}
Выполнение этого приводит к ошибке "getData неоднозначен".
Container<Impl<AnotherClass>> c = new Container(new Impl<AnotherClass>());
Collection<AnotherClass> coll = c.getA().getData();
Я в тупике по этому поводу.
Решение
Похоже, что это вызвано ошибкой плагина groovy. http://jira.codehaus.org/browse/GRECLIPSE-373.Это вообще не проблема java.Спасибо за помощь и приношу свои извинения.
Другие советы
Collection<T> getData()
определенный в Impl
должно быть сделано публичный.Если я делаю это, код компилируется чисто для меня.
Как говорили другие постеры, я не вижу этой проблемы в Eclipse 3.5.0, работающем на JDK 1.6.0.14 (при исправлении ограниченной видимости getData()
способ).
Я предлагаю сделать чистую сборку (Project / Clean в Eclipse).Кроме того, могут помочь версии Eclipse и Java, которые вы используете.
-- Flaviu Cipcigan
Ваш отредактированный пример отлично работает для меня (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();
}
[Отредактируйте, чтобы отразить обновленный вопрос]
Это даже не должно компилироваться, поскольку вы уменьшаете видимость метода из общедоступной области в область пакета:
public class Impl<T extends AnotherClass> implements InterfaceA<Collection<T>> {
Collection<T> getData() {
// get the data
}
}
И это все еще компилируется для меня (Eclispe 3.4, OS X, 1.5), так что не знаю, в чем именно проблема:
тесты температуры упаковки;
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();
}
}
}
То, что у вас здесь есть, кажется законным.Возможно, Eclipse показывает ошибку, которой в противном случае не должно быть.
Перейдите в Windows > Настройки > Java > Компилятор > Ошибки / Предупреждения.В разделе "Общие типы" убедитесь, что Eclipse не сообщает об ошибке ни для одной из перечисленных операций (если вы этого тоже не хотите).У меня все мои данные в этом разделе установлены в положение "Предупреждение".Затем я бы попробовал обновить проект и перезапустить Eclipse.
Редактировать:После того, как был опубликован обновленный пост, я получил предупреждение (по-прежнему не ошибку) в строках использования, в котором говорится: "Контейнер - это необработанный тип.Ссылки на контейнер универсального типа должны быть параметризованы:".Это может быть исправлено с помощью:
Container<Impl<Date>> c = new Container<Impl<Date>>(new Impl<Date>());
(В моем примере я использую java.util.Date как вместо 'AnotherClass').