我正在尝试创建一个方法,它接受一个枚举值并返回一个对象,该对象被转换为基于该枚举值的类。例如,我有一个名为 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”是两个类,它们都扩展了一个名为“Component”的类。它们里面的内容对于这个问题并不重要。
一个实体会有一个分配给它们的组件列表(例如,一个实体可能有饥饿感,而另一个可能有健康,而另一个可能两者都有)。
我的目标是在实体内部创建一个方法,当从 ComponentType 枚举中传入一个值时,将返回一个转换为该值对应类类型的组件对象。因此,如果您传入 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);
将返回转换为“Component”而不是“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”的变量,我必须手动更改它。
最佳答案
您需要 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;
}
关于java - 根据输入的枚举值返回一个转换对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26433334/