2016-03-08 9 views
0

列表陣列I具有如下類結構:流利可迭代從包含泛型類

abstract class Role; 
class Employee extends Role; 
class Student extends Role; 
class Employer extends Role; 

另外我有在其中予存儲可接受的角色的枚舉。

public enum RoleEnum 
{ 
     EMPLOYEE ("Employee", Employee.class), 
     STUDENT ("Student", Student.class), 
     EMPLOYER ("Employer", Employer.class); 

     final private String name; 

     final private Class<? extends Role> pRoleClass; 

     private RoleEnum(final String name, final Class<? extends Role> pRoleClass) 
     { 
      this.name = name; 
      this.pRoleClass = pRoleClass; 
     } 
} 

我要的是從RoleEnums名單得到Class<? extends Role>類型的元素的數組。我正在使用Guava圖書館的FluentIterable,我正在嘗試的是類似FluentIterable.from(list).transform(function).toArray(Class<? extends PartyRole>)的東西。然而,我設法做的是一種解決方法和一種黑客行爲。它看起來是這樣的:

(Class<R>[]) FluentIterable.from(roles) 
         .transform(new Function<RoleEnum, Class<R>>() 
         { 
          @Override public Class<R> apply(final RoleEnum role) 
          { 
           return (Class<R>) role.getRoleClass(); 
          } 
         }) 
         .toList().toArray(new Class[0])); 

其中

class RoleComboWidget<R extends Role> 

是從那裏我調用該方法的類和

ImmutableList<RoleEnum> roles; 
+1

我不確定在這裏看到一個問題。另外,就它的價值而言,泛型和數組之間基本上的任何交互都需要這樣的hackery。泛型和數組真的不能很好地混合。 –

+0

爲什麼你不會像'返回Collections.stream(RoleEnum.values())。map(enumVal - > enumVal.pRoleClass).toArray(Class <?extends Role> :: new);'在Java 8中代替? – Neil

+0

我們仍然在使用Java 7,希望當我們遷移到Java 8時,使用lambda表達式和Java 8的所有強大工具,事情會更加美好。 –

回答

1

你看到的是陣列泛型相結合的效果。 Java中的數組在運行時完全鍵入:組件類型在運行時可用,加載/存儲操作類型檢查並可能會引發異常。

這需要組分型是一個reifiable型,但參數化類型等RoleComboWidget<W>不是。泛型是在Java中通過在編譯時添加的不可見轉換實現的,但是一旦程序運行,JVM實際上不知道這是否是List<String>List<Integer>。回到你的問題,如果你在控制API,當需要數組而不是集合(或流)時要小心:很少有好處(通常在性能上)優於缺點(通常在源代碼維護中) 。另外,要警告(編譯已經警告你),對SomeParameterizedType<T>[]的轉換總是不被檢查:根據前面解釋的事情,最終可能會出現錯誤類型的對象,這些對象可能會使程序崩潰甚至停止。