Java:如何覆盖这个泛型方法?

标签 java generics overriding type-erasure

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 实体),该方法包含以下逻辑:

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

对于 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 , 并且派生类被锁定 TMyType你应该没事。

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

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/

相关文章:

java - 如何防止ConcurrentModificationException?

java - 正则表达式字符组合

c# - 在 C# 中使用泛型创建数学库

java - 无法访问泛型类型的 Enum<?>.valueOf(String) 方法(或如何获取泛型参数的 .class)?

C# 将泛型委托(delegate)传递给构造函数

java - java中的非重写方法?

java - 转换参数如何影响 java 中的覆盖和重载方法?

java - 如何使用Play返回415不支持的媒体类型?

java - Hibernate @Where 子句在 HSQL 和 MySQL 之间不一致

ios - 使用可用的 : <unknown>:0: error: 'xxx' is only available on iOS 11. 0 或更新版本覆盖 open var