Обобщение сопоставимого интерфейса - PullRequest
0 голосов
/ 03 октября 2018

Identity Interface был внедрен в систему несколько лет назад.В этот момент мы получили необходимость, чтобы каждая идентичность была сопоставимой.Одним из вариантов является добавление дополнительного типа & Comparable к объявлению идентификации:

interface Identity<K> {

}

class Handler<T extends Identity<?> & Comparable<T>> {

  Handler(T value) {
    Util.<T>handle(value);
  }
}

class Handler2<T extends Identity<?> & Comparable<T>> {

  Handler2(T value) {
    Util.<T>handle(value);
  }
}

interface Util {

  static <T extends Comparable<T>> void handle(T value) {
  }
}

Одним из основных недостатков является то, что огромный объем кода должен быть дополнен идентичной информацией (например, & Comparable ).Очень элегантным решением было бы расширить Comparable интерфейс с Identity One:

interface Identity<K> extends Comparable<Identity<K>>{

}

Но в этом случае класс Handler выделит ошибку компиляции:

error: дескриптор метода в интерфейсе Util не может быть применен к данным типам;обязательно: T # 1 найдено: T # 2 причина: явный аргумент типа T # 2 не соответствует объявленным границам. Сопоставимо, где T # 1, T # 2 - переменные типа: T # 1 расширяет Comparable, объявленный в дескрипторе метода.(T # 1) T # 2 расширяет идентичность, объявленную в классе Handler

Каковы возможные решения в этой ситуации?

1 Ответ

0 голосов
/ 03 октября 2018

После изменения Identity на то, что вы предложили

interface Identity<K> extends Comparable<Identity<K>>{

}

У вас есть два варианта.Либо:

class Handler<T, U extends Identity<T>>
{
    Handler(U value) {
        Util.handle(value);
    }
}

Пример использования:

Handler<String, Identity<String>> stringHandler = new Handler<>(new FooIdentity());

или

class Handler<T>
{
    Handler(Identity<T> value)
    {
        Util.handle(value);
    }
}

Пример использования:

final Handler<String> stringHandler = new Handler<>(new FooIdentity());

И Util банкаоставить без изменений.

...