2017-01-31 12 views
8

В проекте Spring Data CrudRepository предоставляет сложные функции CRUD для управляемого класса сущности.Что означает <S extends T> save (S entity); в весеннем репозитории?

public interface CrudRepository<T, ID extends Serializable> 
extends Repository<T, ID> { 

    <S extends T> S save(S entity); 

    T findOne(ID primaryKey); 

    Iterable<T> findAll(); 

    Long count(); 

    void delete(T entity); 

    boolean exists(ID primaryKey); 

    // … more functionality omitted. 
} 

В общем, я знаю, что «S расширяет T» означает, что то есть S, возвращаемый тип операции сохранения, должен быть подтипом T. Почему необходимо добавить такие, как ограничение? Я думаю, что было бы хорошо делать что-то вроде этого:

T save (T entity); 

Как и в

void delete(T entity); 

Я гугле, чтобы получить дополнительную помощь, и я понял, следующий вопрос на StackOverflow себя, но это ISN» т действительно для меня ясно:

Spring CrudRepository: why to invent a new generic type S

спасибо.

+2

Я думаю, что вы правы. 'S' является избыточным, а дизайн подписи является ошибкой. – ZhongYu

ответ

8

Если вы должны были иметь как

T save (T entity); 

Тогда единственной переменной можно присвоить результат должен быть типа T.

Так что, если у вас есть CrudRepository<Animal,AnimalID> repository, и у вас есть

Dog dog = getDog(); 
Dog savedDog = repository.save(dog); 

Вы получили бы ошибку компиляции - вы не можете присвоить результат Dog, как это должно быть типа T, в этот случай, Animal.

Вам нужно будет проверить, действительно ли возвращаемое значение было типа Dog, и если да, то наложите его на Dog, чтобы поместить его в savedDog.

С объявлением, как оно есть, это означает, что вы можете назначить его переменной того же типа, что и исходный аргумент, так как это позволит разрешение по типу.

В декларации не указывается, как не животные животные будут сохранены, если вообще будут. Все, что он делает, это разрешить вернуть результат на Dog, если он был первоначально Dog.