public <S extends T> List<S> save(Iterable<S> entities) {
//...
}
如果我用下面的方法覆盖
@Override
public List<MyType> save(Iterable<MyType> structures) {
List<MyType> result = new ArrayList<>();
//...
return result;
}
我收到以下错误:
method does not override or implement a method from a supertype
name clash: save(Iterable<MyType>) in MyTypeRepositoryImpl and <S>save(Iterable<S>) in SimpleJpaRepository have the same erasure, yet neither overrides the other
where S,T are type-variables:
S extends T declared in method <S>save(Iterable<S>)
T extends Object declared in class SimpleJpaRepository
我该如何解决这个问题?我不需要该方法是通用的,事实上它不应该是。我的意思是说
@Override
public <S extends MyType> List<S> save(Iterable<S> structures) {
List<S> result = new ArrayList<>();
//...
return result;
}
将不起作用,因为该方法可以创建与 List 不“兼容”的新 MyType 对象。
我怎样才能让它工作?
编辑:
澄清一下。我正在尝试覆盖 Spring 数据 SimpleJpaRepository 的不同 save() 方法(由 QuerydslJpaRepository 扩展)
类定义:
public class MyTypeRepositoryImpl
extends QueryDslJpaRepository<MyType, Long>
implements MyTypeRepository
@NoRepositoryBean
public interface MyTypeRepository
extends JpaRepository<MyType, Long>,
QueryDslPredicateExecutor<MyType>
还有这个(来自 Spring Data)
public class QueryDslJpaRepository<T, ID extends Serializable>
extends SimpleJpaRepository<T, ID>
implements QueryDslPredicateExecutor<T>
编辑 2:
该方法为每个元素调用 save(MyType 实体),该方法包含以下逻辑:
- 实体有一个唯一的字段
- 获取该字段值并检查具有该值的实体是否已存在
- 如果是,则使用该实体(调用 entityManager.merge)-> 不起作用返回 MyType 而不是 S
- 如果没有创建一个新的 -> 这里创建一个新的对象。不适用于通用类型
对于 4. 我可以设置 id = null 并使用传入的对象。这对 3 不起作用。
所以我很疑惑为什么这个方法有这个签名。这使它对我来说无法使用,我不明白为什么我会使用 Ts DAO 保存 T 的子类。保存方法是唯一带有 .所有其他人只使用 T。我可以只转换为 S 以使其编译,但这看起来也很丑......因为除 T 之外的任何其他类型都会导致异常。
最佳答案
要使一种方法覆盖另一种方法,它必须至少应用于被覆盖方法的所有有效参数。您的基本方法是通用的 public <S extends T> List<S> save(Iterable<S> entities)
.所以它会接受任何类型 S
延伸 T
.但是,您的覆盖更具限制性,因为它只接受 MyType
的集合。 ,因此它不是有效的覆盖。
如果您的基类定义为 T
, 方法只接受 T
, 并且派生类被锁定 T
至 MyType
你应该没事。
为了给出更好的答案,我们需要查看这两个类的类声明。我建议如下:
class MyClass<T>{
public List<T> save(Iterable<T> entities);
}
class OtherClass extends MyClass<MyType>{
public List<MyType> save(Iterable<MyType> entities);
}
编辑:
如果你无法控制基类(你似乎没有),你就会被 public <S extends MyType> List<S> save(Iterable<S> structures)
困住。签名。这是因为重写的方法是泛型化的,所以重写的方法也必须是
关于Java:如何覆盖这个泛型方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13049420/