2017-01-31 17 views
8

Trong dự án Spring Data, CrudRepository cung cấp chức năng CRUD tinh vi cho lớp thực thể đang được quản lý.Điều đó có nghĩa là gì <S extends T> lưu (thực thể S); trong kho lưu trữ mùa xuân?

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

Nói chung, tôi biết những gì "S kéo dài T" có nghĩa là, ví dụ rằng S, kiểu trả về của lưu hoạt động, phải subtype của T. Tại sao nó cần thiết để thêm như hạn chế? Tôi nghĩ rằng đó sẽ là một cái gì đó tốt làm như thế này:

T save (T entity); 

Như trong

void delete(T entity); 

Tôi đã googled để tìm sự giúp đỡ nhiều hơn và tôi đã tìm ra sau câu hỏi về stackoverflow bản thân nhưng nó isn' t thực sự rõ ràng cho tôi:

Spring CrudRepository: why to invent a new generic type S

cảm ơn bạn.

+2

Tôi nghĩ bạn đúng. 'S' là thừa, và thiết kế chữ ký là một sai lầm. – ZhongYu

Trả lời

8

Nếu bạn đã có nó như

T save (T entity); 

Sau đó biến duy nhất bạn có thể gán kết quả đến sẽ phải là kiểu T.

Vì vậy, nếu bạn có một CrudRepository<Animal,AnimalID> repository, và bạn có

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

Bạn sẽ nhận được một lỗi biên dịch - bạn không thể gán kết quả cho Dog, vì nó có phải loại T, trong trường hợp này, Animal.

Bạn cần phải kiểm tra xem giá trị trả lại có thực sự là loại Dog hay không và nếu có, hãy chuyển đến Dog để đặt giá trị đó vào savedDog.

Với tuyên bố như vậy, nó có nghĩa là bạn có thể gán nó cho một biến cùng loại với đối số ban đầu, vì độ phân giải loại sẽ cho phép điều đó.

Bản thân tuyên bố không chỉ rõ cách các phần không phải động vật của con chó được lưu nếu có. Tất cả những gì nó làm là cho phép gán kết quả trở lại Dog nếu ban đầu nó là Dog.

Các vấn đề liên quan