I am trying to make a method that takes an Enum value and returns an object that is casted to a class based on that Enum value. For example, I have an Enum called 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" and "HungerComponent" are two classes that both extend a class called "Component". What is inside them is not important for this question.
An Entity would have a list of Components that they are assigned (For example, one entity may have hunger, while another may have health, and another may have both).
My objective is to create a method inside the Entity that when a value from the ComponentType Enum is passed in, a Component object casted to the corresponding class type for that value is returned. So if you passed in ComponentType.HEALTH, the method would return an object casted to HealthComponent. Here is what I am trying, but it is not working: (Edit: see below)
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;
}
For the above method, when passing in a type of ComponentType.HEALTH:
entity.getComponentByType(ComponentType.HEALTH);
an object casted to "Component" rather than "HealthComponent" would be returned. I want it to return an object casted to HealthComponent, not Component.
Is there any way to do this? I feel like this should be possible. My reason for trying to find a way to do this is because it seems like doing all this casting:
HealthComponent component = (HealthComponent) entity.getComponentByType(ComponentType.HEALTH);
is a bit wasteful since the method could (hopefully) assume what I want to cast to by the ComponentType passed in.
Edit (More info):
Taking a closer look at the results, I noticed that my method above some-what works. What I mean by this is that in Eclipse, if I type out:
component = entity.getComponentByType(ComponentType.HEALTH);
(the component variable is not defined yet) and then hover over getComponentByType to see what it is returning, it says it is returning <Component> Component
However, if I manually define the variable type (most of the time I just let Eclipse create the variables for me) like this:
HealthComponent component = entity.getComponentByType(ComponentType.HEALTH);
And then hover over getComponentByType to see what it is returning, it says it is returning <HealthComponent> HealthComponent and it does compile and run. So it technically works, but not in the way I'd like it to. This is a small issue because if I tell Eclipse to create a local variable for me in the first example, it would create a variable of type "Component" which I would have to manually change.
entity.<HealthComponent>getComponentByType(ComponentType.HEALTH).Componentcan refer to an object whose class is a sub-type ofComponent.