簡體   English   中英

基於輸入枚舉值返回轉換對象

[英]Returning a casted object based on input Enum value

我正在嘗試創建一個采用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> Component

但是,如果我手動定義變量類型(大多數時候我只是讓Eclipse為我創建變量),如下所示:

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

然后將鼠標懸停在getComponentByType上以查看它返回的內容,它表示它返回<HealthComponent> HealthComponent並且它確實編譯並運行。 所以它在技術上有效,但不是我喜歡的方式。 這是一個小問題,因為如果我告訴Eclipse在第一個例子中為我創建一個局部變量,它將創建一個“Component”類型的變量,我必須手動更改。

您希望getComponentByType()的編譯時返回類型取決於用於選擇組件的參數。 這可以通過泛型來實現,但前提是參數實際上包含您需要的編譯時類型信息。

不幸的是,您不能將類型參數添加到枚舉值(請參閱此問題 ),但如果您再次查看自己的代碼,您可能會意識到您已經有一個對象可以恰當地描述您想要獲得的組件,並且會發生這種情況攜帶我們需要的類型信息:每個組件類型的Class<>對象!

所以,這是我對你的功能的建議(沒有編譯或測試,要注意,我的Java可能會生銹):

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

我參加晚會已經晚了4年,但我遇到了它,因為我有類似的情況,想要一個很好的解決方案。

有可能通過為枚舉提供一種提取和轉換的方式而不是依賴於試圖找出類型的實體來解決這個問題。

例如,您可以像這樣在ComponentType枚舉中添加一個方法:

public <C extends Component> C fromEntity(Entity entity) {
    List<Component> componentList = entity.getComponentList();
    // add your existing iteration and type casting logic here
}

然后,而不是嘗試這個:

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

你可以寫這樣的東西

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

在我的情況下,我想要一個帶有枚舉鍵的地圖,並使用這樣的解決方案:

https://gist.github.com/hiljusti/5240d42e827b77e65f41f0a7dfac4406

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM