Общий Java-класс, который хранит сопоставимые - PullRequest
5 голосов
/ 29 ноября 2011

У меня есть общий класс Java, который хранит сопоставимые:

public class MyGenericStorage<T extends Comparable<T>> {
    private T value;

    public MyGenericStorage(T value) {
        this.value = value;
    }

    //... methods that use T.compareTo()
}

У меня также есть абстрактный класс Person:

public abstract class Person implements Comparable<Person>

и два конкретных подкласса, профессор и студент:

public class Professor extends Person
public class Student extends Person

Теперь, когда я хочу создать MyGenericStorage, я получаю сообщение об ошибке:

//error: type argument Student is not within bounds of type-variable T
MyGenericStorage<Student> studStore = new MyGenericStorage<Student>(new Student());

//this works: 
MyGenericStorage<Person> persStore = new MyGenericStorage<Person>(new Student());

Я думаю, это потому, что у меня есть фундаментальная проблема с пониманием дженериков. Может кто-нибудь объяснить мне, а также, как это исправить?

EDIT:

Я изменил MyGenericStorage на следующее:

public class MyGenericStorage<T extends Comparable<? super T>> 

и теперь, похоже, работает. Может кто-нибудь объяснить, почему?

Ответы [ 3 ]

6 голосов
/ 29 ноября 2011

Это можно исправить с помощью следующего объявления для MyGenericStorage:

class MyGenericStorage<T extends Comparable<? super T>> { …

Это означает, что T должна иметь реализацию Comparable, которая принимает некоторый супертип T.В случае Student и Professor супертип, представленный границей (?), имеет вид Person.


Обновление: "теперь это похоже на работу. Можеткто-то объяснит почему? "

Ну, я попробовал в своем первоначальном ответе, но позвольте мне дать ему еще один выстрел.

? super T означает" некоторый супертип T ".Предположим, что T в этом случае - Студент.Итак, Student должен реализовать Comparable «для некоторого супертипа Student»

Student extends Person, который реализует Comparable<Person>.Итак, Student действительно реализует Comparable «для некоторого супертипа Student».

Если у вас есть вопросы по поводу Generics Java, лучше всего начать с FAQ Анжелики Лангер. В этом случае может быть полезна запись об ограниченных подстановочных знаках .

5 голосов
/ 29 ноября 2011

Ваша проблема в том, что Person расширяет Comparable<Person>, так что все в порядке, но Student расширяет Person и, следовательно, расширяет Comparable<Person>, а не Comparable<Student>.

В своем ограничении вы говорите <T extends Comparable<T>>, поэтому они должны быть точно такого же типа . Производные типы не принимаются .

1 голос
/ 29 ноября 2011
public class MyGenericStorage<T extends Comparable<T>>

Выше требуется, чтобы у вас был тип, заданный универсальному классу, для расширения класса, который может быть разделен с самим собой. Короче говоря, вы говорите, что Person должен реализовывать Comparable<Student> и Comparable<Professor>. Вот почему это не может быть использовано.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...