簡體   English   中英

最簡單的方法來轉換類 <T> 到一個班級 <E extends Enum<E> &gt;不丟失類型信息

[英]Simplest way to cast a Class<T> to a Class<E extends Enum<E>> without losing type information

我有一個方法createFoo()創建的實例Foo<T>使用Class<T>實例為T 現在我想擴展該方法以將使用枚舉類型進行的調用轉發給方法createEnumFoo() 從第一個方法調用第二個方法似乎是非平凡的。 下面是我如何設法使用兩個未經檢查的強制轉換和一個額外的方法,我想擺脫所有這些的例子。

方法castEnumType()是必需的,因為我找不到將Class<?> castEnumType()轉換為Class<E extends Enum<E>>而不將E綁定到某處的方法。 這涉及一個未經檢查的強制轉換,因為我還沒有找到使用Class.asSubclass() 在創建Foo實例之后,我需要將它從Foo<E>Foo<T>事件,盡管ET將始終是相同的類型。

我無法削弱createEnumFoo()的簽名,因為它調用Enum.valueOf(enumType, ...)並要求其結果為E類型。

final class Example {
    <E extends Enum<E>> Foo<E> createEnumFoo(Class<E> enumType) {
        // This makes use of e.g. Enum.valueOf(enumType, ...).
        return null;
    }

    <E extends Enum<E>> Class<E> castEnumType(Class<?> enumType) {
        return (Class<E>) enumType;
    }

    <T> Foo<T> createFoo(Class<T> type) {
        if (Enum.class.isAssignableFrom(type))
            return (Foo<T>) createEnumFoo(castEnumType(type));
        else
            // Here we would do something else or maybe throw an exception.
            return null;
    }

    interface Foo<T> {
    }
}

有更簡單的方法嗎?


一些背景

為了澄清我面臨的問題,我將解釋這個問題是如何在我正在進行的項目中出現的:

在遇到此問題的代碼中, Foo<T>實際上是Converter<T> ,它是一個接口,它允許將T實例序列化並反序列化為JSON值:

public interface Converter<T> {
    JsonObject encode(T value);

    T decode(JsonObject data);
} 

createFoo()實際上是一個方法converterForType() ,它接受一個Class<T>實例並動態調度到一堆靜態方法和字段,這些方法和字段創建/包含特定於項目的常見Java類型和類型的轉換器。 通常,當需要轉換器時,直接訪問適當的方法/字段,但有些地方只在運行時知道類型,這是使用converterForType()地方。

現在我想擴展該方法,通過將枚舉類型轉換為包含枚舉常量名稱的JSON字符串來自動處理枚舉類型。 這就是我需要從converterForType()調用方法enumConverter() converterForType() 這是enumConverter()的實現:

public static <E extends Enum<E>> Converter<E> enumConverter(final Class<E> enumClass) {
    return new Converter<E>() {
        public JsonObject encode(E value) {
            return Json.convert(value.name());
        }

        public E decode(JsonObject data) {
            return Enum.valueOf(enumClass, data.asString());
        }
    };
}

那么,使用createEnumFoo方法的原始類型
編輯:@Feuermurmel在評論中報告的修復編譯錯誤

@SuppressWarnings({ "unchecked", "rawtypes" })
final class Example
{
    <E extends Enum<E>> Foo<E> createEnumFoo(Class enumType)
    {
        // This makes use of e.g. Enum.valueOf(enumType, ...).
        Enum x = Enum.valueOf(enumType, "x");
        return (Foo<E>) x;
    }

    <T extends Enum> Foo<T> createFoo(Class<T> type)
    {
        if (Enum.class.isAssignableFrom(type))
            return (Foo<T>) createEnumFoo(type);
        else
            // Here we would do something else or maybe throw an exception.
            return null;
    }

    interface Foo<T>
    {
    }
}

暫無
暫無

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

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