2014-12-29 25 views
2

假設我有一個簽名如何製作一個可以容納類<T>的泛型枚舉?

<T>IInterface<T> method(Class<T> myClass) 

是否有可能寫枚舉可以存放類的類型才能夠實例傳遞給方法?

method(MyEnum.STEP) 

和STEP是一類。

其實我想改變方法的簽名而不是Class<T> myClass但枚舉。但我不想修改返回值類型<T>IInterface<T>

<T>IInterface<T> method(MyEnum type) 

回答

6

枚舉常量的值始終是一個對象,它是enum類的一個實例。你不能讓它有不同的價值;既不是對班級的引用,也沒有其他任何內容。

您可以在枚舉類型,可以抱你想每個枚舉常量的任何值添加實例字段:

enum MyEnum { 
    STEP(Step.class), 
    FOO(Foo.class), 
    BAR(Bar.class); 

    public final Class<?> klass; 

    private MyEnum(Class<?> klass) { 
     this.klass = klass; 
    } 
} 

(使用變量名klass因爲class是保留關鍵字)。

你可以調用這個:

method(MyEnum.STEP.klass); 

但是,它不保留泛型類型的信息。該klass領域是每一個枚舉常量Class<?>型的,所以method(MyEnum.STEP.klass)返回類型將是IInterface<?>,而不是IInterface<Step>

枚舉不能是通用的,所以它們的字段對於不同的常量不能有不同的類型。如果您需要在常量中保留泛型類型信息,則必須放棄使用枚舉來實現此目的,而使用類來僞造它。然後,你可以聲明每個常量與不同類型:

class MyConstant<T> { 
    public static final MyConstant<Step> STEP = new MyConstant<>(); 
    public static final MyConstant<Foo> FOO = new MyConstant<>(); 
    public static final MyConstant<Bar> BAR = new MyConstant<>(); 

    private MyConstant() {} 
} 

這會給你幾乎正是你想要的方法簽名:

<T> IInterface<T> method(MyConstant<T> type) 

被調用爲:

IInterface<Step> something = method(MyConstant.STEP); 

如果您還需要運行時可用的類型信息,您可以將類值添加爲常量上的字段,方法與枚舉示例相同:

class MyConstant<T> { 
    public static final MyConstant<Step> STEP = new MyConstant<>(Step.class); 
    public static final MyConstant<Foo> FOO = new MyConstant<>(Foo.class); 
    public static final MyConstant<Bar> BAR = new MyConstant<>(Bar.class); 

    public final Class<T> klass; 

    private MyConstant(Class<T> klass) { 
     this.klass = klass; 
    } 
} 
+0

但這並沒有工作。要求:'IInterface '卻發現:'IInterface ' – barbara

+0

@barbara你說得對,我忽略了你需要使用的枚舉常量來推斷方法的返回類型的事實。我現在編輯了我的答案。 – Boann