Как сделать этот метод Java универсальным

У меня есть метод Java, который я пытаюсь сделать универсальным, чтобы он мог принимать в качестве параметра список из двух разных типов объектов. (Простой пример показан ниже). Эти два разных объекта всегда будут иметь методы getDate() и getHour(). Код выглядит следующим образом:

public <T> List<T> getListOfStuff(List<T> statistics) {

    List<T> resultList = new ArrayList<T>(statistics.size());

    if(statistics.size() > 0){
        resultList.add(statistics.get(0));

        int date = Integer.parseInt(resultList.get(0).getDate());
        int hour = Integer.parseInt(resultList.get(0).getHour());
    }
    return resultList;
}

Однако это не работает. Эти две строки не работают:

int date = Integer.parseInt(resultList.get(0).getDate());
int hour = Integer.parseInt(resultList.get(0).getHour());

Ошибки говорят: "Метод getDate() не определен для типа T" и "Метод getHour() не определен для типа T"

Он предлагает мне добавить приведение к приемнику метода, но он не позволяет мне использовать T и вместо этого навязывает мне имя объекта, как это, что не будет работать для меня:

int date = Integer.parseInt((ObjectName1)resultList.get(0).getDate());
int hour = Integer.parseInt((ObjectName1)resultList.get(0).getHour());

Есть ли способ сделать то, что я хочу здесь?


person Stackman    schedule 11.05.2017    source источник
comment
Это потому, что вы не можете просто создать интерфейс?   -  person Dave Newton    schedule 11.05.2017
comment
Есть ли у этих двух разных типов общий предок? то есть базовый класс или интерфейс   -  person fps    schedule 11.05.2017
comment
Точнее, эти методы унаследованы от общего предка?   -  person shmosel    schedule 11.05.2017
comment
А что такое ObjectName1? Это общий предок двух упомянутых вами типов или это один из типов, который имеет методы getDate и getHour?   -  person fps    schedule 11.05.2017
comment
@DaveNewton да   -  person Stackman    schedule 12.05.2017
comment
@FedericoPeraltaSchaffner да, но, к сожалению, методы getDate() и getHour() не определены в этом классе, и я не могу изменить этот класс.   -  person Stackman    schedule 12.05.2017
comment
@shmosel Да, см. комментарий выше   -  person Stackman    schedule 12.05.2017
comment
@Stackman, но можете ли вы изменить ObjectName1 и его родственный класс?   -  person fps    schedule 12.05.2017
comment
@Stackman Я имею в виду, почему вы не можете создать общий интерфейс и реализовать его как ObjectName1, так и (допустим) ObjectName2?   -  person fps    schedule 12.05.2017


Ответы (2)


Вы захотите использовать следующее:

public <T extends ObjectName1> List<T> getListOfStuff(List<T> statistics) {
    List<T> resultList = new ArrayList<>(statistics.size());

    if (!statistics.isEmpty()) {
        resultList.add(statistics.get(0));

        int date = Integer.parseInt(resultList.get(0).getDate());
        int hour = Integer.parseInt(resultList.get(0).getHour());
    }

    return resultList;
}

Единственные List, которые можно передать этому методу, теперь должны либо содержать ObjectName1, либо объект, который его расширяет.

person Jacob G.    schedule 11.05.2017
comment
Спасибо, теперь я понимаю. К сожалению, это не сработает в моей ситуации, потому что оба класса имеют методы getDate() и getHour(), но эти методы определены в этих двух классах, а не в одном из общих суперклассов, от которых наследуются два класса. Так что это, вероятно, признак плохого дизайна класса, я думаю. Эти общие свойства/методы действительно должны быть в общем суперклассе. Если бы это было так, я бы смог использовать этот способ сделать метод универсальным. - person Stackman; 12.05.2017

В вашем методе указано использовать тип T, о котором компилятор знает только то, что он расширяет Object. Object не имеет вызванных вами методов. Вы должны утверждать, что у типа есть методы, которые вы используете. Для этого вам нужен <T extends Foo>, где Foo — это тип с этими методами.

ObjectName1 — одно из худших имен для типа.

person Lew Bloch    schedule 11.05.2017
comment
Спасибо за информацию. Это имеет смысл. Что касается имени «ObjectName1» - я изменил имя типа, когда разместил здесь вопрос, так как не хотел включать реальный код. Это просто для примера. - person Stackman; 12.05.2017