Java:如何覆盖这种通用方法?

public  List save(Iterable entities) { //... } 

如果我使用以下方法来覆盖

 @Override public List save(Iterable structures) { List result = new ArrayList(); //... return result; } 

我收到以下错误:

 method does not override or implement a method from a supertype name clash: save(Iterable) in MyTypeRepositoryImpl and save(Iterable) in SimpleJpaRepository have the same erasure, yet neither overrides the other where S,T are type-variables: S extends T declared in method save(Iterable) T extends Object declared in class SimpleJpaRepository 

我怎么解决这个问题? 我不需要该方法是通用的,事实上它不应该是。 我的意思是

 @Override public  List save(Iterable structures) { List result = new ArrayList(); //... return result; } 

无法工作,因为该方法可以创建一个新的MyType对象,它不与List“兼容”。

我怎样才能做到这一点?

编辑:

为了澄清。 我正在尝试覆盖Spring数据SimpleJpaRepository的不同save()方法(由QuerydslJpaRepository扩展)

课程定义:

 public class MyTypeRepositoryImpl extends QueryDslJpaRepository implements MyTypeRepository @NoRepositoryBean public interface MyTypeRepository extends JpaRepository, QueryDslPredicateExecutor 

而这(来自Spring Data)

 public class QueryDslJpaRepository extends SimpleJpaRepository implements QueryDslPredicateExecutor 

编辑2:

该方法为每个元素调用save(MyType实体),该方法包含以下逻辑:

  1. entity有一个独特的字段
  2. 获取该字段值并检查具有该值的实体是否已存在
  3. 如果是,则使用该实体(调用entityManager.merge) – >不起作用返回MyType而不是S.
  4. 如果没有创建新的 – >这里创建了新对象。 不适用于generics类型

对于4.我可以设置id = null并使用传入的对象。 这不适用于3。

所以我很困惑为什么这个方法有这个签名。 它使我无法使用它,我不知道为什么我会使用Ts DAO保存T的子类。 保存方法是唯一的。 所有其他人只是使用T.我可以强制转换为S使其编译,但这看起来也很难看……因为除了T之外的任何其他类型都会导致exception。

对于覆盖另一个方法的一种方法,它必须至少应用于重写方法的所有有效参数。 您的基本方法是通用public List save(Iterable entities) 。 因此它将接受任何扩展T类型S 但是,您的覆盖更具限制性,因为它只接受MyType集合,因此它不是有效的覆盖。

如果您的基类使用T定义,并且方法只接受T ,并且派生类将T锁定为MyType那么您应该没问题。

为了给出更好的答案,我们需要查看两个类的类声明。 我建议如下:

 class MyClass{ public List save(Iterable entities); } class OtherClass extends MyClass{ public List save(Iterable entities); } 

编辑:

如果您无法控制基类(您似乎没有),那么您将无法使用public List save(Iterable structures)签名。 这是因为重写的方法是通用的,因此重写方法也必须如此

取决于您如何定义,以下工作

 public class TestGenerics2 { public  List save(Iterable entities) { return new ArrayList(); } } public class TestGenerics3 extends TestGenerics2 { @Override public  List save(Iterable entities) { return super.save(entities); } } 

这是一个编译并显示如何使用它的示例:

 abstract class A { abstract public  List save(Iterable entities); } class B extends A> { @Override public > List save(Iterable entities) { return null; } } class C { public void useIt() { B b = new B(); Iterable> it = new ArrayList>(); b.save(it); } } 

A类使用原始签名定义方法。 B类实现它并为类型参数T选择List 。 最后,类C使用此方法, Iterable whoregenerics类型是List的子类。

以来

 public  List save(Iterable entities) 

给出,你的覆盖必须是

 public  List save(Iterable structures) 

并且您的实现必须尊重S可能是MyType的真实子类型。

你的方法

 public List save(Iterable structures) 

不是正确的覆盖:

  • 因为Java> = 1.5允许协变返回类型而ListList的子类型,这没关系,但是
  • Java仅允许不变的参数类型,但IterableIterable的子Iterable ,因此您的编译器错误消息。

我的解决方案是不要覆盖这一点,只是创建一个服务类来完成所需的逻辑并保持存储库不变。