Подтвердить что ты не робот

Разница между универсальным суперклассом и суперклассом

Я не могу понять разницу между двумя фрагментами кода ниже. Может ли кто-нибудь помочь мне с простым объяснением?

Прежде всего, я должен сказать, что у меня много классов, которые расширяют суперкласс с именем BaseEntity, и каковы различия, преимущества и недостатки следующих фрагментов?

// 1
public <T extends BaseEntity> T getName(T t) {
    return t;
}

// 2
public BaseEntity getName(BaseEntity t) {
    return t;
}
4b9b3361

Ответ 1

Первый фрагмент более гибкий, поскольку он сохраняет фактический тип T. Предположим, что у вас есть подкласс:

class SubEntity extends BaseEntity {}

В первом случае вы можете написать:

SubEntity result = getName(new SubEntity());

Но во втором случае вам понадобится бросок:

SubEntity result = (SubEntity)getName(new SubEntity());

Ответ 2

Основное различие при использовании двух методов - это возможная необходимость литья во втором случае.

Скажем, у вас есть:

public class MyEntity extends BaseEntity {
}

С помощью первого метода вы можете иметь что-то вроде:

MyEntity myEntity = ...
MyEntity entity = getName(myEntity);

В то время как со вторым методом вам нужно будет написать:

MyEntity entity = (MyEntity)getName(myEntity);

Это потому, что вы указываете конкретный тип в своем первом методе.

Ответ 3

Я удивлен, что никто не упомянул об этом в предыдущих ответах, но есть более фундаментальное различие между двумя объявлениями метода (что является причиной необходимости кастинга во втором случае). Это различие не имеет значения для тривиальных методов, которые вы здесь предоставили, но это может повлиять на метод, который делает что-то отличное от простого возвращения его аргумента.

Ваше первое объявление метода требует, чтобы возвращаемый тип был тем же типом, что и аргумент. Таким образом

public <T extends BaseEntity> T getName(T t) {
    return new SubEntity(); // Where SubEntity extends BaseEntity
}

не компилируется, тогда как

public BaseEntity getName(BaseEntity t) {
    return new SubEntity(); // Where SubEntity extends BaseEntity
}

является полностью законным, даже если BaseEntity, переданный в метод, является совершенно другим типом от SubEntity.

Ответ 4

1) В вашем первом коде у вас есть Ограничения метода return должны быть subclasses от BaseEntity, а входной параметр должен быть тем же самым подклассом BaseEntity.

2) В вашем втором коде у вас есть return и param метода должен быть subclasses от BaseEntity.