Java:如何覆盖这个通用方法? 公共列表保存(可编辑实体){ //... }
如果我使用以下方法来重写Java:如何覆盖这个通用方法? 公共列表保存(可编辑实体){ //... },java,generics,overriding,type-erasure,Java,Generics,Overriding,Type Erasure,如果我使用以下方法来重写 public <S extends T> List<S> save(Iterable<S> entities) { //... } @覆盖 公共列表保存(Iterable结构){ 列表结果=新建ArrayList(); //... 返回结果; } 我发现以下错误: @Override public List<MyType> save(Iterable<MyType> structures)
public <S extends T> List<S> save(Iterable<S> entities) {
//...
}
@覆盖
公共列表保存(Iterable结构){
列表结果=新建ArrayList();
//...
返回结果;
}
我发现以下错误:
@Override
public List<MyType> save(Iterable<MyType> structures) {
List<MyType> result = new ArrayList<>();
//...
return result;
}
方法不重写或实现超类型中的方法
名称冲突:MyTypeRepositoryImpl中的save(Iterable)和SimpleParepository中的save(Iterable)具有相同的擦除,但两者都不重写另一个
其中S、T是类型变量:
S扩展在方法save(Iterable)中声明的T
T扩展类SimpleParepository中声明的对象
我怎样才能解决这个问题?我不需要这个方法是泛型的,事实上它不应该是泛型的。我的意思是
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
@覆盖
公共列表保存(Iterable结构){
列表结果=新建ArrayList();
//...
返回结果;
}
将不起作用,因为该方法可以创建与列表“不兼容”的MyType新对象
我怎样才能做到这一点
编辑:
请澄清。我正在尝试覆盖Spring数据SimpleParepository(由QuerydslJpaRepository扩展)的不同save()方法
类别定义:
@Override
public <S extends MyType> List<S> save(Iterable<S> structures) {
List<S> result = new ArrayList<>();
//...
return result;
}
公共类MyTypeRepositoryImpl
扩展QueryDslJpaRepository
实现MyTypeRepository
@菜豆
公共接口MyTypeRepository
这是一个假设,
QueryDSL谓词执行器
这(来自Spring数据)
公共类QueryDslJpaRepository
扩展SimpleParepository
实现QueryDslPredicateExecutor
编辑2:
该方法为每个元素调用save(MyType实体),该方法包含以下逻辑:
所以我很困惑为什么这个方法有这个签名。它使我无法使用,我不明白为什么我要使用Ts-DAO保存t的子类。save方法是唯一具有此功能的方法。其他所有方法都使用T。我可以将其强制转换为S以使其编译,但这看起来也很难看……因为T以外的任何其他类型都会导致异常。对于一个方法重写另一个方法,它必须至少应用于被重写方法的所有有效参数。基本方法是泛型
公共列表保存(Iterable实体)
。因此,它将接受扩展T
的任何类型S
。但是,您的覆盖更具限制性,因为它只接受MyType
的集合,因此它不是有效的覆盖
如果您使用T
定义了基类,并且该方法只接受T
,并且派生类被锁定到T
到MyType
,那么您应该可以
为了给出更好的答案,我们需要查看这两个类的类声明。我建议如下:
public class QueryDslJpaRepository<T, ID extends Serializable>
extends SimpleJpaRepository<T, ID>
implements QueryDslPredicateExecutor<T>
class-MyClass{
公共列表保存(Iterable实体);
}
类OtherClass扩展了MyClass{
公共列表保存(Iterable实体);
}
编辑:
如果您不能控制基类(看起来好像没有),那么您就只能使用公共列表保存(Iterable structures)
签名。这是因为重写方法是泛化的,因此重写方法也必须是
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 T> List<S> save(Iterable<S> entities)
公共列表保存(Iterable结构)
您的实现必须考虑到S可能是MyType的真正子类型
你的方法
public <S extends MyType> List<S> save(Iterable<S> structures)
公共列表保存(Iterable结构)
不是正确的覆盖:
- 因为Java>=1.5允许返回类型,并且
是List
的子类型,所以这是可以的,但是List
- Java只允许固定参数类型,但
是Iterable
的子类型,因此编译器会显示错误消息Iterable
- 下面是一个编译示例,展示了如何使用它:
public List<MyType> save(Iterable<MyType> structures)
抽象类A{
抽象公共列表保存(Iterable实体);
}
B类扩展了A类{
@凌驾
公共列表保存(Iterable实体){
返回null;
}
}
C类{
公共空间使用IT(){
B=新的B();
Iterable it=新的ArrayList();
b、 保存(它);
}
}
类
A
定义具有原始签名的方法。类B
实现它,并为类型参数T
选择List
。最后,classC
将此方法用于Iterable
whore泛型类型是列表的子类
取决于您如何定义,以下工作
abstract class A<T> {
abstract public <S extends T> List<S> save(Iterable<S> entities);
}
class B extends A<List<Integer>> {
@Override
public <S extends List<Integer>> List<S> save(Iterable<S> entities) {
return null;
}
}
class C {
public void useIt() {
B b = new B();
Iterable<ArrayList<Integer>> it = new ArrayList<ArrayList<Integer>>();
b.save(it);
}
}
公共类TestGenerics2{
公共列表保存(Iterable实体){
返回新的ArrayList();
}
}
公共类TestGenerics3扩展了TestGenerics2{
@凌驾
公共列表保存(Iterable实体){
返回super.save(实体);
}
}
我的解决方案是根本不重写它,而是创建一个执行所需逻辑的服务类,并保持存储库不变。如何声明包含的类?列出“不兼容”是什么意思?从原始的
参数来看,该类可以通过执行实现InterfaceName
之类的操作来使用,而不必处理从注释到其他答案的子类以及您正在扩展一个您无法控制的类这一事实,我相信您是被迫使用公共列表保存(Iterable结构)
。这是因为爱
abstract class A<T> {
abstract public <S extends T> List<S> save(Iterable<S> entities);
}
class B extends A<List<Integer>> {
@Override
public <S extends List<Integer>> List<S> save(Iterable<S> entities) {
return null;
}
}
class C {
public void useIt() {
B b = new B();
Iterable<ArrayList<Integer>> it = new ArrayList<ArrayList<Integer>>();
b.save(it);
}
}
public class TestGenerics2<T> {
public <S extends T> List<S> save(Iterable<S> entities) {
return new ArrayList<S>();
}
}
public class TestGenerics3 extends TestGenerics2<Number> {
@Override
public <S extends Number> List<S> save(Iterable<S> entities) {
return super.save(entities);
}
}