Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/grails/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 接口中的泛型方法返回未检查的强制转换_Java_Spring_Generics_Interface_Casting - Fatal编程技术网

Java 接口中的泛型方法返回未检查的强制转换

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

所以我有一系列相关的接口,其中一个包含其他3个接口(由setter和getter实现)

虽然这些接口的实例可以在管理(从映射中存储和检索)时保持为接口契约;当它们到达一个处理bean时,它们需要能够将自己显示为实现的类

因此,我能够做到以下几点:

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;
}