Returning a casted object based on input Enum value
我正在尝试创建一个方法,该方法获取枚举值并返回一个基于该枚举值强制转换为类的对象。例如,我有一个名为componenttype的枚举:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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"是两个扩展名为"component"的类的类。在这个问题上,他们内心的东西并不重要。
一个实体会有一个被分配的组件列表(例如,一个实体可能饥饿,而另一个实体可能健康,另一个实体可能两者都有)。
我的目标是在实体内部创建一个方法,当传入component type枚举中的值时,将返回一个组件对象,该对象被强制转换为该值的相应类类型。因此,如果传入componenttype.health,该方法将返回一个强制转换为healthcomponent的对象。这是我正在尝试的,但它不起作用:(编辑:见下文)
1 2 3 4 5 6 7 8 9 10 11 12 | 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类型时:
1 | entity.getComponentByType(ComponentType.HEALTH); |
将返回强制转换为"component"而不是"healthcomponent"的对象。我希望它返回一个转换为healthcomponent的对象,而不是组件。
有什么办法吗?我觉得这是可能的。我之所以想找到一种方法来做到这一点,是因为它看起来像是在做所有这些演员:
1 | HealthComponent component = (HealthComponent) entity.getComponentByType(ComponentType.HEALTH); |
这有点浪费,因为方法可以(希望)假定我希望通过传入的componentType强制转换的内容。
编辑(详细信息):
仔细观察结果,我注意到我的方法在某些方面有效。我的意思是,在Eclipse中,如果我键入:
1 | component = entity.getComponentByType(ComponentType.HEALTH); |
(组件变量尚未定义)然后将鼠标悬停在getcomponentByType上,查看返回的内容,它表示返回
但是,如果我手动定义变量类型(大多数时候我只是让Eclipse为我创建变量),如下所示:
1 | HealthComponent component = entity.getComponentByType(ComponentType.HEALTH); |
然后将鼠标悬停在getcomponentbytype上,查看它返回的是什么,它说它返回
您希望
不幸的是,您不能将类型参数添加到枚举值中(参见本问题),但是如果您再次查看自己的代码,您可能会意识到您已经有了一个对象,该对象恰当地描述了您想要获取的组件,并且正好包含了我们需要的类型信息:每个组件类型的
所以,这是我对您的功能的建议(没有编译或测试,请注意,我的Java可能生锈):
1 2 3 4 5 6 7 8 9 10 11 | public <T extends Component> T getComponentByType(Class<T> type) { for(Component component : componentList) { if(component.getClass() == type) { return (T)component; } } return null; } |
我迟到了4年,但我遇到这个问题是因为我遇到了类似的情况,想要一个好的解决方案。
可以通过给枚举一种提取和强制转换的方法来解决这个问题,而不是依赖一个试图找出类型的实体。
例如,可以向componenttype枚举添加如下方法:
1 2 3 4 | public <C extends Component> C fromEntity(Entity entity) { List<Component> componentList = entity.getComponentList(); // add your existing iteration and type casting logic here } |
稍后不再尝试:
1 | HealthComponent component = (HealthComponent) entity.getComponentByType(ComponentType.HEALTH); |
你可以写这样的东西
1 | HealthComponent component = ComponentType.HEALTH.fromEntity(entity); |
在我的例子中,我希望有一个带有枚举键的映射,并使用如下解决方案:
https://gist.github.com/hiljust/5240d42e827b77e65f41f0a7dfac4406