2014-12-05 59 views
0

我有一個類EnumSet<E extends Enum<E>>,它有一個方法public void include(E e)需要一個枚舉常量,並將其放入一個列表中,表示一組給定的枚舉。鑄造到java中的通用參數

現在我想通過反射從xml文件加載EnumSets,以便我可以迭代ove rall enum常量並將它們包含在加載的集合中。

Object[] enum_const = Class.forName(cur.getAttributeValue("type")).getEnumConstants(); 
field.set(obj, Class.forName(cur.getAttributeValue("type")).newInstance()); 
for (Object o : enum_const) { 
    if (o.toString().equalsIgnoreCase(cur.getText())) { 
     ((EnumSet<?>) field.get(obj)).include((E) o); 
     // Include each matching EnumConstant.. 
    } 
} 

最後投是不可能的,因爲E是不是在這方面進行訪問。有沒有人有這個問題的解決方案?

+0

只需刪除cast。模板參數被原始類型中的對象替換。 – talex 2014-12-05 15:18:11

+0

你有沒有試過[EnumSet.allOf](https://docs.oracle.com/javase/7/docs/api/java/util/EnumSet.html#allOf%28java.lang.Class%29)? – OldCurmudgeon 2014-12-05 15:32:16

+0

也許你可以使用[typetools](http://search.maven.org/#artifactdetails%7Cnet.jodah%7Ctypetools%7C0.3.1%7Cjar)庫來訪問它們。 – bhdrkn 2014-12-05 15:39:00

回答

0

你可以使用一個通用的helper方法:

@SuppressWarnings("unchecked") 
static <E extends Enum<E>> void uncheckedInclude(EnumSet<?> enumSet, Object element) { 
    EnumSet<E> enumSetWithNarrowedType = (EnumSet<E>) enumSet; 
    E elementWithNarrowedType = (E) element; 
    enumSetWithNarrowedType.include(elementWithNarrowedType); 
} 

... 

if (o.toString().equalsIgnoreCase(cur.getText())) { 
    uncheckedInclude((EnumSet<?>) field.get(obj), o); 
} 

注意,有兩個選中石膏這裏正在進行,一個用於設置一個用於元素。從EnumSet<?>EnumSet<E>的劇組是必要的,因爲通用通配符不能表達遞歸的E extends EnumSet<E>界限。

很顯然@SuppressWarnings("unchecked")是有希望的類型將是正確的,因爲即使JVM不能快速失敗,因爲錯誤的未經檢查的轉換 - 確保良好的文檔並確保輔助方法不被濫用。