Java:如何覆盖这个泛型方法? [英] Java:How to override this generic method?
问题描述
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实体),该方法包含以下逻辑:
- 实体具有唯一字段
- 获取该字段值并检查具有该值的实体是否已经存在
如果是,则使用该实体(调用entityManager.merge) - >不起作用返回MyType not S
- 如果不创建新的 - >这里创建新的对象。不适用于泛型
对于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:
- entity has a field which is unique
- get that fields value and check if entity with that value already exists
- if yes, use that entity (call to entityManager.merge) -> does not work returns MyType not S
- 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屋!