Java, дженерики и PECS: все еще возникают проблемы с пониманием C-части; конкретный пример?
Я выложу одну ссылку здесь: Collections.sort()
, На SO было много постов, касающихся парадигмы PECS, включая эту. В моем личном коде я довольно часто использую дженерики, но только когда-либо использовал P-часть (то есть <X extends SomethingElse>
).
Collections.sort
ожидает в качестве своего аргумента дженериков <T extends Comparable<? super T>>
, Я не вижу, где super
пинает там. У вас есть конкретный пример того, почему это необходимо?
В то время как я в этом, я глубоко боюсь, что я не понимаю всех последствий P либо... Я прочитал много-много ссылок, не имея ясного, очевидного доказательства того, что P - это P, а C - это C...
РЕДАКТИРОВАТЬ Что касается, возможно, уже есть ответ здесь ": нет, извините. Я прочитал эту ссылку, и многие другие на SO. Это все еще не говорит мне основной механизм за всем этим. Два ответа, данные мне до сих пор дают мне подсказывает, на самом деле больше, чем все ссылки, которые я мог найти до сих пор.
3 ответа
Например
List<Interger> myIntegers = Arrays.asList(5, 2, 3);
List<Long> myLongs = Arrays.asList(5L, 2L, 3L);
MyNumberComparator myNumberComparator = new Comparator<Number>(){...}
Collections.sort(myIntegers, myNumberComparator ); // Number is "super" class of Integer
Collections.sort(myLongs , myNumberComparator ); // Number is "super" class of Long
Таким образом, "супер" здесь позволяет повторно использовать MyNumberComparator как для сортировки целых чисел, так и для сортировки длинных.
Я не могу видеть, где супер пинает там. У вас есть конкретный пример того, почему это необходимо?
Скажи, у тебя есть класс Animal
, что сравнимо со всеми Animal
s:
public class Animal implements Comparable<Animal>
Теперь скажем, у вас есть класс Dog
, который расширяет Animal
:
public class Dog extends Animal
Теперь вопрос в том, может Dog
сравнить с другим Dog
? (т.е. вы можете сделать myDog.compareTo(yourDog)
) Ответ конечно. Dog
как Animal
, сравнимо со всеми Animal
с, в том числе Dog
с (а также Cat
с).
Тем не мение, Dog
не реализует Comparable<Dog>
так что предел T extends Comparable<T>
не будет работать для T = Dog
,
Но для сортировки нам важно только то, что тип может сравнивать с самим собой (что Dog
сможет сделать). Таким образом, подходящая наименее ограничительная граница T extends Comparable<? super T>
, который работает для Dog
,
Попробуйте создать список номеров:
List<Number> list = new ArrayList<Number>(Arrays.asList(2, 3.14, 5, 0, 42, 2.5));
Теперь попробуйте отсортировать это:
Collections.sort(list);
Глядя на общий аргумент <T extends Comparable<? super T>>
, это эквивалентно в этом случае <Number extends Comparable<? super Number>>
, Однако класс Number не реализует такой компаратор. Следовательно, код не компилируется и заставляет вас создавать свой собственный.