Java:如何覆盖这个泛型方法? [英] Java:How to override this generic method?

查看:730
本文介绍了Java:如何覆盖这个泛型方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  public< S extends T>列表与LT; S>保存(Iterable< S>实体){
// ...
}

如果我使用以下方法覆盖

  @Override 
public List< MyType>保存(Iterable< MyType>结构){
List< MyType> result = new ArrayList<>();
// ...
返回结果;
}

我得到以下错误:

 方法不会覆盖或实现超类型的方法

名称冲突:MyTypeRepositoryImpl中的save(Iterable< MyType>)和< S> save (Iterable< S>)具有相同的擦除,但都不会覆盖其中S,T是类型变量的其他

S扩展在方法< S> save中声明的T(Iterable< S> ;)
T extends在类SimpleJpaRepository中声明的对象

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

  @Override 
public< S extends MyType>列表与LT; S>保存(Iterable< S>结构){
List< S> result = new ArrayList<>();
// ...
返回结果;





$ b

不会工作,因为该方法可以创建一个新的MyType对象,它不是与列表兼容。




$ b

编辑:

澄清。我试图覆盖Spring数据SimpleJpaRepository的不同save()方法(由QuerydslJpaRepository扩展)



类定义:

  public class MyTypeRepositoryImpl 
扩展QueryDslJpaRepository< MyType,Long>
实现MyTypeRepository

@NoRepositoryBean
public interface MyTypeRepository
扩展JpaRepository< MyType,Long> ;,
QueryDslPredicateExecutor< MyType>

这个(来自Spring Data)

  public class QueryDslJpaRepository< T,ID extends Serializable> 
扩展了SimpleJpaRepository< T,ID>
实现QueryDslPredicateExecutor< T>

编辑2:

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


  1. 实体具有唯一字段

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

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



所以我很困惑为什么这个方法有这个签名。它使我无法使用,我不明白为什么我会用Ts DAO保存T的一个子类。保存方法是唯一的。所有其他人只是使用T.我可以投给S来编译它,但这似乎也很丑陋...因为除T以外的任何其他类型都会导致异常。

解决方案

我的解决方案是根本不覆盖它,而是创建一个服务类来完成所需的逻辑并保持版本库不变。


public <S extends T> List<S> save(Iterable<S> entities) {
        //...
}

If I use following method to override

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

I get following error:

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

How can I solve this? I don't need the method to be generic and in fact it should not be. What I mean is that

@Override
public <S extends MyType> List<S> save(Iterable<S> structures) {
    List<S> result = new ArrayList<>();
    //...
    return result;
}

Will not work as the method can create a new Object of MyType which is not "compatible" to List.

How can I make this work?

EDIT:

For clarification. I'm trying to override the different save() methods of Spring data SimpleJpaRepository (which is extented by QuerydslJpaRepository)

Class defintions:

public class MyTypeRepositoryImpl
    extends QueryDslJpaRepository<MyType, Long>
    implements MyTypeRepository

@NoRepositoryBean
public interface MyTypeRepository
    extends JpaRepository<MyType, Long>,
    QueryDslPredicateExecutor<MyType> 

And this (from Spring Data)

public class QueryDslJpaRepository<T, ID extends Serializable> 
extends SimpleJpaRepository<T, ID> 
implements QueryDslPredicateExecutor<T>

EDIT 2:

The method calls save(MyType entity) for each element and that method contains following logic:

  1. entity has a field which is unique
  2. get that fields value and check if entity with that value already exists
  3. if yes, use that entity (call to entityManager.merge) -> does not work returns MyType not S
  4. if no create a new one -> here new object is created. Does not work with generic type

For 4. I can just set id = null and use the passed in object. That does not work for 3.

So I'm very puzzled why this method has this signature. It makes it unusable for me and i don't get why I would save a subclass of T using Ts DAO. the save methods are the only ones with . All others just use T. I could just cast to S to make it compile but that seems ugly too...as any other type than T would lead to an exception.

解决方案

My solution was to not override this at all but to create a service class that does the needed logic and leave repository untouched.

这篇关于Java:如何覆盖这个泛型方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆