Здесь есть абстрактный класс BaseA.

//class definition
public abstract class BaseA {
    void doSomething();
}

И есть два клиента, использующие класс BaseA следующим образом.

//the client A 
class clientA {
    void clientA(BaseA obj){
        obj.doSomething();
    }
    ...

//the client B  
class clientB<T extends BaseA> {
    void methodB(T obj){
        obj.doSomething();

    }
    ...

Вопрос в том, есть ли разница между этими двумя? Какой из них лучше и почему? Пожалуйста, порекомендуйте. * Вопрос не ограничивается производительностью.

2
Ando 21 Дек 2019 в 03:12

1 ответ

Лучший ответ

Разница между ClientA и ClientB заключается в том, что ClientB связан не только с BaseA, но и с T. Поскольку T не может уменьшить объем каких-либо методов в BaseA, интерфейс идентичен.

Согласно документам преимущества дженериков:

  • Более строгие проверки типов.
  • Устранение забросов
  • Включение общих алгоритмов

Когда использование дженериков ограничено, как показано в вопросе, в этом отношении мало пользы. Однако здесь применяются более строгие проверки типов.

Основное отличие состоит в том, что T extends BaseA заставляет параметр иметь точный тип T. Если класс использовал только BaseA, в метод можно было бы передать любой подкласс BaseA.

Пример:

class SubA extends BaseA {}
class SubB extends BaseA {}

class ClientA {
    void method(BaseA obj) {
        obj.doSomething();
    }
}
class ClientB<T extends BaseA> {
    void method(T obj) {
        obj.doSomething();
    }
}

ClientA a = new ClientA();
a.method(new SubA());
a.method(new SubB());

ClientB<SubA> b = new ClientB<>();
b.method(new SubA());
b.method(new SubB()); // fails

В то время как ClientA допускает передачу любого BaseA, ClientB позволяет ограничить его использование определенным подтипом.

2
ldz 24 Дек 2019 в 01:58