2016-01-29 71 views
2

提供類看到,如果一個類型變量表示給定類的超

class EnvironmentHolder<V> { 
    protected Map<String,V> environment; 

    // Get the Type of V via Google's GSon library; this part 
    // works okay 
    protected final Type VALUE_TYPE = new TypeToken<V>() {}.getType(); 

    ... 

    public void importEnvironment(Class aClass) { 
     // NEEDS AN IMPLEMENTATION 
    } 
} 

其中V一定的參考類型,我試圖收集所有的aClass的 靜態成員分別是「分配的爲」一類型 V   —的是,那些子類,的實施方案中,或 同一類V

我該怎麼做?我想用下面的實施importEnvironment

for (Field field : aClass.getFields()) { 
    ((Class) V).isAssignableFrom(field.getType()) 
} 

我看到Class的確是Type實施者,但我不 知道如何安全地進行鑄造。 (Type還包括 非引用類型,這是不是Class ES)

注:不說,直到你認爲它通過 「類型擦除將不讓在運行時這樣做。」有相當多的問題認爲這是一個幾乎自動的響應,這似乎意味着反射API不可能在Java中實現。

謝謝!

+3

「使用谷歌的番石榴圖書館獲得V的類型;這部分工作正常」 - 你確定嗎?創建匿名子類的要點是將類型信息直接編碼到其中。這是我的理解,如果你在這裏放置一個泛型類型V,你就失去了TypeToken的目的。 – nickb

+0

哎呦,我的壞!我的意思是Gson。好吧,無論如何,它似乎工作。但也許我錯過了一些東西。這是Gson的官方[建議](https://github.com/google/gson/blob/master/UserGuide.md#collections-examples)。 – jpaugh

+1

當然,但我不認爲他們的例子中的任何地方都會看到它們使用泛型類型實例化TypeToken(就像您使用TypeToken 一樣)。在你引用的文檔中,他們有'TypeToken >'出於某種原因 - 他們永遠不會擁有'TypeToken >',因爲TypeToken是沒用的。從本質上講,TypeToken只有在用非泛型類型實例化時纔有效。 – nickb

回答

2

由於類型擦除,您無法對現有代碼執行此操作:您不知道V在運行時。

您需要的Class<V>一個實例,因此你可以說:

clazz.isAssignableFrom(field.getType()); 

您可以通過這爲EnvironmentVariable<V>施工時間參數,或者把它作爲的importEnvironment另一個參數。我會說前者更方便,因爲你只需要做一次,而不是每當你調用importEnvironment

class EnvironmentHolder<V> { 
    private final Class<V> clazz; 

    EnvironmentHolder(Class<V> clazz) { 
     this.clazz = clazz; 
    } 

    public void importEnvironment(Class<?> aClass) { 
     for (Field field : aClass.getFields()) { 
      if (clazz.isAssignableFrom(field.getType())) { 
       // ... 
      } 
     } 
    } 
} 

請注意,您還可以通過傳遞(和存儲)的TypeToken<V>實例做到這一點 - 如果V本身是一個泛型類型,這可能是更方便。但是,正如@nickb所記錄的那樣,你實際上需要通過那個例子。你不能依靠泛型來創建它。

還請注意Class<?> aClass上的<?> - 這裏沒有理由使用原始類型。

相關問題