簡體   English   中英

如何從泛型類型參數中獲取 `.class` 屬性?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM