beg*_*er_ 10 java generics overriding type-erasure
public <S extends T> List<S> save(Iterable<S> entities) {
//...
}
Run Code Online (Sandbox Code Playgroud)
如果我使用以下方法来覆盖
@Override
public List<MyType> save(Iterable<MyType> structures) {
List<MyType> result = new ArrayList<>();
//...
return result;
}
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
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
Run Code Online (Sandbox Code Playgroud)
我怎么解决这个问题?我不需要该方法是通用的,事实上它不应该是.我的意思是
@Override
public <S extends MyType> List<S> save(Iterable<S> structures) {
List<S> result = new ArrayList<>();
//...
return result;
}
Run Code Online (Sandbox Code Playgroud)
无法工作,因为该方法可以创建一个新的MyType对象,它与List不兼容.
我怎样才能做到这一点?
编辑:
为了澄清.我正在尝试覆盖Spring数据SimpleJpaRepository的不同save()方法(由QuerydslJpaRepository扩展)
课程定义:
public class MyTypeRepositoryImpl
extends QueryDslJpaRepository<MyType, Long>
implements MyTypeRepository
@NoRepositoryBean
public interface MyTypeRepository
extends JpaRepository<MyType, Long>,
QueryDslPredicateExecutor<MyType>
Run Code Online (Sandbox Code Playgroud)
而这(来自Spring Data)
public class QueryDslJpaRepository<T, ID extends Serializable>
extends SimpleJpaRepository<T, ID>
implements QueryDslPredicateExecutor<T>
Run Code Online (Sandbox Code Playgroud)
编辑2:
该方法为每个元素调用save(MyType实体),该方法包含以下逻辑:
对于4.我可以设置id = null并使用传入的对象.这不适用于3.
所以我很困惑为什么这个方法有这个签名.它使我无法使用它,我不知道为什么我会使用Ts DAO保存T的子类.保存方法是唯一的.所有其他人只使用T.我可以直接转换为S使其编译,但这看起来也很难看......因为除了T之外的任何其他类型都会导致异常.
Joh*_*n B 10
对于覆盖另一个方法的一种方法,它必须至少应用于重写方法的所有有效参数.您的基本方法是通用的public <S extends T> List<S> save(Iterable<S> entities).所以它会接受任何S扩展的类型T.但是,您的覆盖更具限制性,因为它只接受集合MyType,因此它不是有效的覆盖.
如果您已经定义了基类T,并且只接受了方法T,并且派生类被锁定T到MyType您应该没问题.
为了给出更好的答案,我们需要查看两个类的类声明.我建议如下:
class MyClass<T>{
public List<T> save(Iterable<T> entities);
}
class OtherClass extends MyClass<MyType>{
public List<MyType> save(Iterable<MyType> entities);
}
Run Code Online (Sandbox Code Playgroud)
编辑:
如果您无法控制基类(您似乎没有),那么您将无法使用public <S extends MyType> List<S> save(Iterable<S> structures)签名.这是因为重写的方法是通用的,因此重写方法也必须如此
我的解决方案是根本不覆盖它,而是创建一个服务类来执行所需的逻辑并保持存储库不变。