<S扩展T>保存(S实体)是什么意思?在春季存储库中?

2022-09-03 06:36:21

在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.
}

一般来说,我知道“S扩展T”是什么意思,即保存操作的返回类型S必须是T的子类型。为什么有必要添加诸如约束之类的内容?我认为做这样的事情会很好:

T save (T entity);

void delete(T entity);

我已经用谷歌搜索了更多帮助,我已经找到了关于stackoverflow本身的以下问题,但对我来说并不清楚:

Spring CrudRepository:为什么要发明一种新的通用类型S

谢谢。


答案 1

如果你要把它当作

T save (T entity);

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

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

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

您会收到编译错误 - 您无法将结果分配给 ,因为它的类型为 ,在本例中为 。DogTAnimal

您需要检查返回的值是否确实是类型,如果是,请将其转换为 以将其放入 。DogDogsavedDog

使用原样的声明,这意味着您可以将其分配给与原始参数类型相同的变量,因为类型解析将允许这样做。

声明本身没有具体说明如何保存狗的非动物部分(如果有的话)。它所要做的就是允许将结果赋回 a(如果它最初是 .DogDog


答案 2

推荐