java – 根据输入枚举值返回一个转换对象

我正在尝试创建一个采用Enum值的方法,并返回一个基于该Enum值转换为类的对象.例如,我有一个名为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”的类.其中的内容对于这个问题并不重要.

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

我的目标是在Entity中创建一个方法,当传入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);

将返回一个转换为“Component”而不是“HealthComponent”的对象.我希望它返回一个转换为HealthComponent的对象,而不是Component.

有没有办法做到这一点?我觉得这应该是可能的.我试图找到一种方法来实现这一点的原因是因为它似乎在做所有这些演员:

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

有点浪费,因为该方法可以(希望)假设我想通过传入的ComponentType来转换.

编辑(更多信息):

仔细看看结果,我注意到我的方法在上面 – 有效.我的意思是在Eclipse中,如果我输入:

component = entity.getComponentByType(ComponentType.HEALTH);

(组件变量尚未定义)然后将鼠标悬停在getComponentByType上以查看它返回的内容,它表示它正在返回< 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;
}
点赞