Могут ли явные параметры типа избыточны? - PullRequest
6 голосов
/ 26 июня 2019

У меня есть класс с параметром типа.

class MyObject<IdType> {

    @Setter
    @Getter
    private IdType id;
}

И я подумал, что могу добавить какой-нибудь метод для удобства, поэтому я сделал.

<T extends MyObject<? super IdType>> void copyIdTo(T object) {
    object.setId(getId());
}

< T extends MyObject<? extends IdType>> void copyIdFrom(T object) {
    object.copyIdTo(this);
}

И я только что понял, что яможет сделать это.

void copyIdTo(MyObject<? super IdType> object) {
    object.setId(getId());
}

void copyIdFrom(MyObject<? extends IdType> object) {
    object.copyIdTo(this);
}

Эти два набора методов эквивалентны?Какой способ (или стиль) предпочтительнее?

Ответы [ 2 ]

5 голосов
/ 26 июня 2019

В вашем случае два подхода эффективно эквивалентны.Они оба ограничивают тип аргумента MyObject<...> или подтипом.

Поскольку ваши примеры методов возвращают void, нет никакой реальной выгоды от того, чтобы сделать метод универсальным.Единственная важная вещь для вашего метода - это аргумент MyObject<...>, за исключением того, что реальный тип не имеет смысла.Добавление возможности сделать тип аргумента более конкретным ничего не добавляет для реализации метода и ничего не делает для вызывающей стороны.Другими словами, это не имеет значения "пух".

Так что для ваших примеров, я бы сказал, предпочли не универсальный вариант.Это чище и проще.


Однако, если ваши методы возвращают заданный аргумент вызывающей стороне, то создание общего метода может оказаться полезным;это позволит вам объявить тип возвращаемого значения как T.Это открывает возможности для вызывающей стороны, такие как цепочка методов или вызов метода «внутри» другого вызова метода, все на основе определенного типа, передаваемого в качестве аргумента.Примером этого в базовой библиотеке может быть Objects.requireNonNull(T).

Еще один хороший пример для того, чтобы сделать метод обобщенным, упоминается @Thilo в комментариях:

Другой случай будетесли ваш метод принимает несколько аргументов.Затем вы можете ввести T, чтобы убедиться, что эти два аргумента имеют один и тот же тип (вместо двух отдельных типов, которые [выполняют] ограничения по отдельности).

Это также может быть применено кодин аргумент, например, Collection<? extends T>.

2 голосов
/ 26 июня 2019

Да, они эквивалентны.Оба набора методов объявляют одно и то же - параметр метода должен иметь тип MyObject<> или совместимый подтип (подкласс).

Единственная причина для объявления T таким образом - это если вам нужносм. T в другом месте, например, тип возвращаемого значения метода, или если у вас есть несколько параметров одного типа, или внутри тела метода.

Я бы предпочел более короткую, простую и понятную версию с меньшим количеством угловых скобок, чтобы повредить глазные яблоки:)

...