是什么意思<S extends T> save(S entity); 在Spring Repository中?

bau*_*048 10 java generics spring repository spring-data

在Spring Data项目中,CrudRepository为正在管理的实体类提供了复杂的CRUD功能.

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.
}
Run Code Online (Sandbox Code Playgroud)

一般来说,我知道"S extends T"意味着什么,即S,保存操作的返回类型,必须是T的子类型.为什么有必要添加诸如约束?我认为做这样的事情会很好:

T save (T entity);
Run Code Online (Sandbox Code Playgroud)

如在

void delete(T entity);
Run Code Online (Sandbox Code Playgroud)

我已经google搜索了更多帮助,我已经在stackoverflow本身上找到了以下问题,但对我来说并不是很清楚:

Spring CrudRepository:为什么要发明一个新的泛型类型S.

谢谢.

Rea*_*tic 12

如果你是这样的话

T save (T entity);
Run Code Online (Sandbox Code Playgroud)

然后,您可以分配结果的唯一变量必须是类型T.

所以,如果你有CrudRepository<Animal,AnimalID> repository,并且你有

Dog dog = getDog();
Dog savedDog = repository.save(dog);
Run Code Online (Sandbox Code Playgroud)

您将收到编译错误 - 在这种情况下,您无法将结果分配给Dog,因为它必须是类型.TAnimal

您需要检查返回的值是否确实是类型Dog,如果是,则将其转换Dog为将其放入savedDog.

通过声明,它意味着您可以将它分配给与原始参数相同类型的变量,因为类型解析将允许它.

声明本身没有具体说明如何保存狗的非动物部分.它所做的就是允许将结果分配回Dog原来的a Dog.