2014-10-17 60 views
2

我想制作一个方法,它需要一个枚举值并返回一个基于该枚举值铸造到类的对象。例如,我有一个枚举称为COMPONENTTYPE:基于输入枚举值返回铸造对象

public enum ComponentType 
{ 
    HEALTH(HealthComponent.class), 
    HUNGER(HungerComponent.class); 

    private Class<? extends Component> componentClass; 

    private ComponentType(Class<? extends Component> componentClass) 
    { 
     this.componentClass = componentClass; 
    } 

    public Class<? extends Component> getComponentClass() 
    { 
     return componentClass; 
    } 
} 

“HealthComponent”和“HungerComponent”两类,这两个延伸一个称为“分量”类。里面的东西对这个问题并不重要。

一个实体将有一个他们被分配的组件列表(例如,一个实体可能有饥饿感,而另一个实体可能有健康状况,另一个可能有两个)。

我的目标是在实体内部创建一个方法,当来自ComponentType Enum的值传入时,将返回一个转换为该值的相应类类型的Component对象。因此,如果您通过ComponentType.HEALTH传递,该方法将返回一个转换为HealthComponent的对象。下面是我想要的,但它不工作:(编辑:见下文)

public <T extends Component> T getComponentByType(ComponentType type) 
{ 
    Class<? extends Component> componentClass = type.getComponentClass(); 
    for(Component component : componentList) 
    { 
     if(component.getClass() == componentClass) 
     { 
      return (T) componentClass.cast(component); 
     } 
    } 
    return null; 
} 

对于上述方法,传入一个类型ComponentType.HEALTH时:

entity.getComponentByType(ComponentType.HEALTH); 

对象铸造成“组件”而不是“HealthComponent”将被退回。我希望它将一个对象传递给HealthComponent,而不是Component。

有没有办法做到这一点?我觉得这应该是可能的。我对试图找到一种方式来做到这一点的原因是因为它看起来像是在做这一切的铸造:

HealthComponent component = (HealthComponent) entity.getComponentByType(ComponentType.HEALTH); 

是有点浪费,因为该方法可以(希望)假设我想通过COMPONENTTYPE投什么在

编辑(更多信息):

以对结果仔细一看,我发现我的上述方法的一些,是什么在起作用。我的意思是,在Eclipse中,如果我输入了:

component = entity.getComponentByType(ComponentType.HEALTH); 

(组件变量尚未确定),然后getComponentByType悬停在看什么它返回,它说,它返回<Component> Component

但是,如果我手动定义变量类型(大部分时间我只是让Eclipse中创建我的变量)是这样的:

HealthComponent component = entity.getComponentByType(ComponentType.HEALTH); 

然后将鼠标悬停在getComponentByType,看看它返回时,说它正在返回<HealthComponent> HealthComponent并且它编译并运行。所以它在技术上是有效的,但不是我喜欢的方式。这是一个小问题,因为如果我告诉Eclipse在第一个示例中为我创建一个局部变量,它将创建一个类型为“Component”的变量,我将不得不手动更改该变量。

+0

所以,当你编译并运行该代码会发生什么? – 2014-10-17 21:01:16

+0

@JBNizet查看我上面的编辑。 – 2014-10-17 21:15:35

+0

这是一个通用的方法,它的返回类型不能由编译器的参数类型推断出来。所以它只能通过分配给它的变量的类型来推断。你总是可以使用'entity。 getComponentByType(ComponentType.HEALTH)'。 – 2014-10-17 21:18:31

回答

1

您希望编译时返回类型getComponentByType()取决于您用于选择组件的参数。这对于泛型是可能的,但只有当参数实际上携带您需要的编译时类型信息时才可能。

不幸的是,你可以不加类型参数枚举值(见this question),但是如果你在自己的代码再看看,你可能会意识到你已经有一个恰当描述你想要得到哪些组件对象,并且恰巧携带我们需要的类型信息:每个组件类型的Class<>对象!

所以,这里是我送给你的功能建议(没有编译或测试,要小心,我的Java可能是生锈):

public <T extends Component> T getComponentByType(Class<T> type) 
{ 
    for(Component component : componentList) 
    { 
     if(component.getClass() == type) 
     { 
      return (T)component; 
     } 
    } 
    return null; 
} 
+0

我想这会对我有用,谢谢! – 2014-10-18 01:54:27