Как следует за обобщающие Java файлы в Eclipse, но не в javac, я публикую еще один фрагмент, который компилируется и работает отлично в Eclipse, но вызывает ошибку компиляции в джавах. (Это предотвращает извлечение фрагмента из проекта из Maven.)
Автономный фрагмент:
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class Main {
public static void main(String[] args) {
Set<Foo<?>> setOfFoos = new HashSet<Foo<?>>();
List<Foo<?>> sortedListOfFoos = asSortedList(setOfFoos);
}
public static <T extends Comparable<T>> List<T> asSortedList(Collection<T> c) {
List<T> list = new ArrayList<T>(c);
java.util.Collections.sort(list);
return list;
}
public static class Foo<T> implements Comparable<Foo<T>> {
@Override
public int compareTo(Foo<T> o) {
return 0;
}
}
}
Компиляция в javac возвращается:
Main.java:11: <T>asSortedList(java.util.Collection<T>) in Main cannot be applied to (java.util.Set<Main.Foo<?>>)
List<Foo<?>> sortedListOfFoos = asSortedList(setOfFoos);
^
При подстановке Foo<?>
с Foo<String>
приведенный выше фрагмент будет компилироваться в javac, что означает, что проблема связана с используемым шаблоном. Поскольку предполагается, что компилятор Eclipse более терпим, возможно ли, что сниппет не является допустимой Java?
(Я использую javac 1.6.0_37 и Eclipse Indigo с уровнем соответствия компилятора 1.6)
( EDIT1: Включен другой пример, который был удален в EDIT2.)
EDIT2: Указывается неутешительный, что сравнение Foo<A>
и Foo<B>
может быть концептуально неправильным и вдохновлено ответом seh, рабочий asSortedFooList
можно записать следующим образом:
public static <T extends Foo<?>> List<T> asSortedFooList(Collection<T> c) {
List<T> list = new ArrayList<T>(c);
java.util.Collections.sort(list);
return list;
}
(Простая подстановка Comparable<T>
с помощью Foo<?>
в определении метода выше).
Таким образом, для javac и imho, как представляется, безопасно сравнивать любые Foo<A>
и Foo<B>
. Но по-прежнему невозможно написать общий метод asSortedList
, который возвращает представление отсортированного списка для общего набора, если его аргумент типа параметризован с помощью подстановочного знака. Я попытался "обмануть" javac, заменив Foo<?>
на S extends Comparable<S>
в asSortedFooList
, но это не сработало.
EDIT3: Позже Rafaelle указал, что есть недостаток в дизайне, поскольку реализация Comparable<Foo<T>>
не нужна, и реализация Comparable<Foo<?>>
обеспечивает ту же функциональность, что позволяет решить начальную задачу по уточненному дизайну.
(Первоначальная причина и преимущество заключались в том, что a Foo<T>
может не заботиться в некоторых целях о конкретном типе, но все же использовать экземпляр конкретного типа T
, он создается для других целей. не может использоваться для определения порядка среди других Foo
s, поскольку он может использоваться в других частях API.
Конкретный пример: предположим, что каждый Foo создается экземпляром другого аргумента для T
. Каждый экземпляр Foo<T>
имеет инкрементирующий id типа int
, который используется при реализации метода compareTo
. Теперь мы можем отсортировать список этих по-разному напечатанных Foo
и не заботиться о конкретном типе T
(выражая его с помощью Foo<?>
) и до сих пор иметь экземпляр конкретного типа T
, доступный для последующей обработки. )