Java: я вообще не понимаю этого определения дженериков

У меня есть несколько методов сортировки, которые для работы должны принимать объект, для которого определено compareTo.

Следующее как часть общего определения:

private static <SomeType extends Comparable<? super SomeType>> 
    void  doSomeSort(SomeType[] a, int left, int right){

кажется, делает свое дело.

Моя проблема в том, что я не совсем понимаю, что за
<SomeType extends Comparable<? super SomeType>>

фактически определяет.
Это означает, что вы можете заменить тип, который является интерфейсом, расширяющим Comparable, который создается сам по себе ...
Я не понимаю.

Не могли бы вы помочь прояснить это определение?


person Cratylus    schedule 01.02.2012    source источник
comment
Возможный дубликат stackoverflow.com/questions/8422078/class-definition -класс-имя /.   -  person Tudor    schedule 01.02.2012


Ответы (5)


Это означает:

SomeType - это класс, расширяющий Comparable<SomeType> или Comparable<Any type that is a superclass or super interface of SomeType>.

Причина ? super SomeType в том, что процедура сортировки может сортировать массив экземпляров SomeType, если SomeType может сравнивать себя с другими экземплярами SomeType. Если случается, что SomeType расширяет SomeSuperType и любой экземпляр SomeSuperType может сравнивать себя с другими экземплярами SomeSuperType, сортировка будет сравнивать их без проблем.

person JB Nizet    schedule 01.02.2012

В конечном итоге все, что вам действительно нужно знать, это то, что это означает:

SomeType x = ...;
SomeType y = ...;
int comparison = x.compareTo(y);

будет компилировать.

Точнее, это означает, что SomeType реализует Comparable<T> для некоторого типа T, который находится в иерархии наследования _5 _... без необходимости указывать, что такое T, но в результате код выше работает :)

person Jon Skeet    schedule 01.02.2012
comment
Но в определении сказано extends Comparable. Не SomeType implements Comparable - person Cratylus; 01.02.2012
comment
@ user384706: Общие ограничения не используют implements, вот и все. Черт возьми, SomeType может быть интерфейсом. - person Jon Skeet; 01.02.2012

Это переводится как:

  • тип SomeType должен расширять или реализовывать класс Comparable
  • сам класс Comparable в этом случае принимает в качестве параметра некоторый тип, назовем его T.
  • тип T должен быть SomeType или суперклассом SomeType.

Классический тип, который соответствует этому шаблону, - Integer, поскольку он реализует Comparable<Integer>.

person Tudor    schedule 01.02.2012

<SomeType extends Comparable<? super SomeType>>

Comparable всегда имеет особый тип шаблона. Итак, Comparable<String> можно сравнить с String, Comparable<BigInteger> можно сравнить с BigInteger и так далее.

Здесь ожидается SomeType, производный от Comparable<T>. Это означает, что SomeType сравнимо с другими экземплярами. Самым тривиальным было бы

<SomeType extends Comparable<SomeType>>

До сих пор должно быть ясно. Все, что сейчас добавлено, представляет собой простое ключевое слово super. Это означает, что SomeType должен быть сопоставим со всем, что имеет тип SomeType или что-либо выше в иерархии производных. В основном это имеет одно преимущество: позже вы можете получить свои собственные / дополнительные типы из SomeType, и этот метод по-прежнему будет иметь обратную совместимость! Классно, а?

Например:

class SomeTypeSuper { ... }
class SomeType extends SomeTypeSuper { ... }    

// Now, in your code both is valid:
// Asuming the method `yourMethod` expects a `<SomeType extends Comparable<? super SomeType>>` as parameter.

yourMethod(new SomeTypeSuper()); // This wouldn't be valid if we had used Comparable<SomeType>
yourMethod(new SomeType());
person poitroae    schedule 01.02.2012
comment
? super SomeType принимает любой класс выше SuperType в иерархии наследования, но не ниже. - person JB Nizet; 01.02.2012
comment
@JBNizet Ага, правильно! Очевидно была оговорка: /. Я его отредактировал. - person poitroae; 01.02.2012

Float - это подкласс Number. Мы могли бы объявить это так:

class Float extends Number implements Comparable<Float>

Но на самом деле наш класс Float намного шире этого. Класс float знает, как сравнивать себя с Integer, Bignums, Double и т. Д. На самом деле наш класс float знает, как сравнивать себя с * any (number.

class Float extends Number implements Comparable<Number>
class Integer extends Number implements Comparable<Number>

Фактически: любой числовой класс должен это делать, поэтому реальное объявление

class Number implements Comparable<Number>
class Integer extends Number
class Float extends Number

Теперь интерфейс Comparable отлично с этим справляется. Если бы он не использовался подстановочными знаками, то числа с плавающей запятой и целые числа не могли бы быть сопоставимы.

Но поскольку это так, вы можете пойти:

Comparable<Number> array[] = new Comparable<Number>[10];
array[0] = Float.getValue(10);     
array[1] = Integer.getValue(11);
sort(array, 0, 1);     

Вы не можете этого сделать без ›? супер T>.

person PaulMurrayCbr    schedule 03.02.2012
comment
Ваш ответ кажется очень близким к этой концепции, но содержит ошибки. Даже ваш примерный код неверен. Вы не можете сделать Comparable<Number> array[] = new .. для начала. - person Cratylus; 06.02.2012