[英]How do I get the `.class` attribute from a generic type parameter?
這個問題的公認答案描述了如何在Generic<T>
類中創建T
的實例。 這涉及將Class<T>
參數傳遞給Generic
構造函數並從中調用newInstance
方法。
然后創建一個新的Generic<Bar>
實例,並傳入參數Bar.class
。
如果新Generic
類的泛型類型參數不是像Bar
這樣的已知類,但它本身是泛型類型參數,你會怎么做? 假設我有一些其他類Skeet<J>
並且我想從該類中創建一個新的Generic<J>
實例。 然后,如果我嘗試傳入J.class
我會收到以下編譯器錯誤:
cannot select from a type variable.
有沒有辦法解決?
對我來說觸發錯誤的具體代碼是:
public class InputField<W extends Component & WidgetInterface>
extends InputFieldArray<W>
{
public InputField(String labelText)
{
super(new String[] {labelText}, W.class);
}
/* ... */
}
public class InputFieldArray<W extends Component & WidgetInterface>
extends JPanel
{
/* ... */
public InputFieldArray(String[] labelText, Class<W> clazz)
throws InstantiationException, IllegalAccessException
{
/* ... */
for (int i = 0 ; i < labelText.length ; i++) {
newLabel = new JLabel(labelText[i]);
newWidget = clazz.newInstance();
/* ... */
}
/* ... */
}
/* ... */
}
發生錯誤,因為我不能寫W.class
。 是否有其他方式傳遞相同的信息?
不允許在類型參數上使用.class
- 由於類型擦除, W
將在運行時被擦除到Component
。 InputField
還需要從調用者那里獲取一個Class<W>
,例如InputFieldArray
:
public InputField(String labelText, Class<W> clazz)
{
super(new String[] {labelText}, clazz);
}
如果您使用的是 Gson 庫,則可以使用TypeToken
輕松獲取T
的類型。 類文檔可在此處獲得:
我是這樣做的:
這是我的類定義:
public class ManagerGeneric <T> {}
這是我的方法:
// Get the type of generic parameter
Type typeOfT = new TypeToken<T>(){}.getType();
// Deserialize
T data = gson.fromJson(json, typeOfT);
由於類型擦除,W 可能不可用。 您應該要求將Class<W>
傳遞到方法中。 你得到一個類對象,它的泛型確保只有W
而沒有子類被傳入,因為協方差。
public InputField(String labelText, Class<W> cls)
{
super(new String[] {labelText}, cls);
}
將采用W.class
而不是WSubtype.class
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.