2015-05-28 86 views
2

好吧,很好。Java enum與類<T>實現接口返回類型

這裏是一個枚舉,它實現了一個接口,該接口使用一個返回'raw type'的方法,該方法在接口中給出了一個關於getCaste()方法的警告。

public enum Thing implements HasCaste { 

    Type1 { 
     @Override 
     public Class getCaste() { 
      return String.class; 
     } 
    }; 
} 

interface HasCaste { 
    public Class getCaste(); 
} 

如果我更改接口的方法:

public <T> Class<T> getCaste(); 

它的變化對Type1的方法簽名未經檢查的警告。如果我再改Type1.getCaste()的簽字:

public <T> Class<T> getCaste() 

然後返回有一個不兼容的類型錯誤,因爲Class<String>不能轉換到Class<T>。如果我然後將返回更改爲(Class<T>) String.class,我們會收到未經檢查的投射警告。

有沒有辦法做到這一點沒有警告?

編輯:

對不起,我沒有在早期添加這一點,但它會是很好的做到這一點:

, Type2 { 
     @Override 
     public Class getCaste() { 
      return Integer.class; 
     } 
    }; 
+1

相關:http://stackoverflow.com/questions/28234960/java-generics-and-enum-loss-of-template-parameters – Radiodef

+0

要編輯,你不能使用枚舉。 – Radiodef

+0

@Radiodef我實際上正在計劃連接這個問題:p(我是那個提問者) – EpicPandaForce

回答

2

你可以只保留返回的類未指定的類型參數:

public enum Thing implements HasCaste { 

    Type1 { 
     @Override 
     public Class<String> getCaste() { 
      return String.class; 
     } 
    }, Type2 { 
     @Override 
     public Class<Integer> getCaste() { 
      return Integer.class; 
     } 
    }; 
} 

interface HasCaste { 
    public Class<?> getCaste(); 
} 
+0

雖然協變覆蓋是不可見的,因爲常量聲明只是「事情」。 – Radiodef

+0

@Radiodef,我如何測試覆蓋不可見? – user121330

+0

嘗試類似'Class c = Thing.Type1.getCaste();'。 http://ideone.com/ij7EwN – Radiodef

2

由於這是在question I asked a while ago that was linked by Radiodef決定,你不能做到這一點與一個enum,只有通過一個模擬的枚舉,實際上是一個類,像這樣。

public abstract class Thing<T> implements HasCaste<T> { 
    public static final Thing<String> Type1 = new Thing<String>() { 
     @Override 
     public Class<String> getCaste() { 
      return String.class; 
     } 
    }; 
    public static final Thing<Integer> Type2 = new Thing<Integer>() { 
     @Override 
     public Class<Integer> getCaste() { 
      return Integer.class; 
     } 
    }; 

    private Thing() { 
    } 
} 

正如你所看到的,這不是一個enum雖然。僅僅是enum是不可能的,因爲枚舉不能有類型參數。

PS:如果你發現這是很有幫助,請看看Radiodef's answer一個更完整的解釋,我瞭解到這從他身上,畢竟:)

+0

另外兩個答案明確完成任務。是不是正確的詞?也許'不應該'會更好? – user121330

+0

如果您嘗試訪問其他兩種解決方案中的「Thing.Type1」,那麼您將不會將類作爲「類」,而將類2作爲類,您將從類「'。 – EpicPandaForce

+0

....哦,但如果你只是想刪除警告,那麼肯定,'類'工程。 – EpicPandaForce

1

假設你要定義幾個不同的「類型」的枚舉常量,那麼可以這樣做:

interface HasCaste { 
    public Class<?> getCaste(); 
} 

public enum Thing implements HasCaste<?> { 

    Type1(String.class), 
    Type2(Integer.class); 

    public final Class<?> clazz; 

    private Thing(Class<?> clazz) { 
     this.clazz = clazz; 
    } 

    @Override 
    public Class<?> getCaste() { 
     return clazz; 
    } 
} 

之一,那麼德爾對於getCaste的未來使用進行打字。枚舉的主要特徵是一個封閉的值域;必須列出班級內所有可能的值。