Java 接口中的泛型方法返回未检查的强制转换
所以我有一系列相关的接口,其中一个包含其他3个接口(由setter和getter实现) 虽然这些接口的实例可以在管理(从映射中存储和检索)时保持为接口契约;当它们到达一个处理bean时,它们需要能够将自己显示为实现的类 因此,我能够做到以下几点:Java 接口中的泛型方法返回未检查的强制转换,java,spring,generics,interface,casting,Java,Spring,Generics,Interface,Casting,所以我有一系列相关的接口,其中一个包含其他3个接口(由setter和getter实现) 虽然这些接口的实例可以在管理(从映射中存储和检索)时保持为接口契约;当它们到达一个处理bean时,它们需要能够将自己显示为实现的类 因此,我能够做到以下几点: public interface IState<S extends IState> { <G extends GameData> G getGameData(); <G> S setGameData(G gameD
public interface IState<S extends IState> {
<G extends GameData> G getGameData();
<G> S setGameData(G gameDataIO);
<P> P getPlayer();
<P> S setPlayer(P player);
<GS> GS getGameState();
<GS> S setGameState(GS gameState);}
公共接口IState{
G getGameData();
S setGameData(G gameDataIO);
P getPlayer();
S-setPlayer(P-player);
GS getGameState();
S setGameState(GS gameState);}
默认实现:
public class DefaultStateNG implements IStateNG<DefaultStateNG> {
private GameData gameDataIO;
private IPlayerState player;
private IGameState gameState;
@Override
public <G extends GameData> G getGameData() {
return (G) gameDataIO;
}
@Override
public <G> DefaultStateNG setGameData(G gameDataIO) {
this.gameDataIO = (GameData) gameDataIO;
return this;
} //..... other accessor methods implemented
公共类DefaultStateNG实现IStateNG{
私有GameData gameDataIO;
私人IPlayerState播放器;
私有IGameState配子状态;
@凌驾
公共G getGameData(){
返回(G)gameDataIO;
}
@凌驾
public DefaultStateNG setGameData(G gameDataIO){
this.gameDataIO=(GameData)gameDataIO;
归还这个;
}//…实现的其他访问器方法
因此,当我在处理器bean中使用它们时,不需要将它们转换到接口的适当实现中
当在返回类型中进行强制转换时,如果出现未选中的强制转换,则会出现问题。我不知道如何处理此类警告。我的意思是,我正在将gameDataIO设置为GameData类型,并且返回应该是GameData类型。为什么会出现警告?我尝试了各种类型的强制转换,到目前为止,唯一一种没有警告的方法是通过预期的class作为参数,然后使用type.cast(returnedObject)
当您的接口定义以下通用方法时,任何提示都将不胜感激。:
<G extends GameData> G getGameData();
这里的实现不知道任何潜在的调用站点。它应该返回调用方所需的特定子类型(G
),但它不能这样做。您正在强制转换,但编译器无法验证它是否安全(因为它不安全),因此会收到未检查的警告
假设我编写了一个类MyGameData扩展了GameData
,并在代码中编写:
IState state=…//待办事项
MyGameData mgd=state.getGameData();
在这种情况下,
被绑定到特定的类型MyGameData
,该类型满足您的API要求,它必须从GameData
继承。但是,您的代码返回一个普通的GameData
而不是我的特定子类,并在运行时导致ClassCastException
大多数其他方法也是如此。要么返回基本类型(GameData
等),而不使用getter等通用方法,要么必须将类型参数G
、GS
和p
添加到IState
界面,而不是按方法添加
编辑以添加,基于此注释:
GameData、Player和其他接口的实现是Spring一开始就注入的。因此,我有接口只是为了确保基本功能,但实现的类需要处理器知道。我做了没有泛型的第一个版本,但我做了大量类型转换,使代码无法读取
你描述的是一个紧密耦合系统的症状。为了定义松散耦合的系统,因为这些通常被认为是一个更好的设计。我鼓励你考虑为什么在你的设计中,处理器需要知道其他接口的实现类型。这是因为接口本身不能完全描述F。该接口实现所需的函数行为?
我找到了一个解决方案,即在已实现处理器的入口点上定义类型。我无法找到使用泛型方法设置类型声明的方法(至少不需要执行未检查的强制转换) 在我明确声明之后,必须进行声明,并且我的处理器bean是所有其他bean连接在一起的地方,因此声明类型是有意义的。不幸的是,对我来说,状态是我的处理方法的I/O对象,所以它还需要在处理器中声明,包括它包含的类 比如:@Component
public class KenoManager implements IGenericGame<DefaultState<
KenoData,
DefaultPlayer,
KenoGameState,
DefaultSystemState>> {
public DefaultState processInit(DefaultState<
KenoData,
DefaultPlayer,
KenoGameState,
DefaultSystemState> state) {
return null;
}
@组件
公共类KenoManager实现IGenericGame>{
公共DefaultState processInit(DefaultState<
基诺达塔,
默认玩家,
甲磺酸基诺加酯,
DefaultSystemState>state){
返回null;
}
当出现配置文件时,我可以使用通配符?来填充声明并使某些bean的注入成为通用的。我认为您不想在这里使用泛型。如果您希望使用不同树中的类而不使用它们的组合父类(最坏情况下的对象),则可以使用泛型。这里,你只需要GameData、Player等。GameData、Player和其他接口的实现是Spring一开始就注入的。因此,我有接口只是为了确保基本功能,但实现的类需要处理器知道。我做了第一个版本,没有泛型,但最后做了大量类型转换使代码不可读。我明白你的意思,但在处理器bean的实现中,我将输入设置为IState的实现,因此传入参数是
DefaultState状态
;然后我可以执行MyGameData mgd=state.getGameData()
;没有问题。我的代码正常工作,正是这个警告困扰着我。从您所说的,我明白了为什么我会收到警告,并且我无法确保类型安全,所以我应该使用抑制警告标记?我不建议抑制此警告(或一般警告),因为这意味着除非情况恰到好处,否则一切都会破裂。这是一种草率的放弃,以后可能会给你带来麻烦。我的建议是,你改变你的API,不要对这些方法使用泛型,因为它们会让你的API提出建议
IState<?> state = ... // TODO
MyGameData mgd = state.getGameData();
@Component
public class KenoManager implements IGenericGame<DefaultState<
KenoData,
DefaultPlayer,
KenoGameState,
DefaultSystemState>> {
public DefaultState processInit(DefaultState<
KenoData,
DefaultPlayer,
KenoGameState,
DefaultSystemState> state) {
return null;
}