簡體   English   中英

實例化T的子類時如何返回泛型T

[英]How to return generic type T when instantiating a subclass of T

我想獲取一個可以返回T類型的對象和T的子代的參數化類

這是代碼:

import java.lang.reflect.InvocationTargetException;

class A {};

class B extends A {};

public class testGenerics<T extends A> {

  T a;

  T getA() {
    return getA(B.class); // Compilation problem:
    //The method getA(Class<T>) in the type testGenerics<T> is not applicable for the arguments (Class<B>)
  }

  T getA(Class<T> clazz) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
      return clazz.getConstructor().newInstance();
  }

}

我是這樣想的:

我聲明的是泛型T,它擴展了A。因此,我可以從Class clazz創建一個擴展了A的T類型的實例。

但是,當我決定從B.class獲取A時(哪個擴展了A):

getA(B.class)

我收到以下錯誤:

類型為testGenerics <T>的方法getA(Class <T>)不適用於參數(Class <B>)

為什么是這樣? 我該如何解決?

您的問題是類定義class testGenerics<T extends A>

這意味着T是在創建該類的實例時定義的,並且可以綁定到A任何子類-可能不是B而是C等。因此,不能保證傳遞B.class匹配。

要解決此問題,請將T的定義置於方法級別:

<T extends A> A getA(Class<T> clazz) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
  return clazz.getConstructor().newInstance();
}

//No generics needed here, since the method above returns A anyways.
//If it'd return T you'd have to change the return type here to B since getA(B.class) binds T to be B now
A getA() throws Exception {
  return getA(B.class); 
}

由於方法級別T在類級別隱藏了定義,因此您需要為此做些事情:使用其他名稱(例如S )或在類級別刪除定義(無論如何在這里都沒有多大意義)。

這是行不通的,因為B不是T 是的, B也擴展了T ,但不是T 假設您還有一個類C extends A並創建了一個testGenerics<C>的實例。 您的getA()方法將實例化B但應返回C 但是,以下內容在進行一些調整后仍然可以正常工作:

testGenerics<B> tg = new testGenerics<B>();
B b = tg.getA(B.class);

如何解決此問題取決於您實際想要做什么。 例如,這允許您實例化A任何子類:

  public <S extends A> S getA(Class<S> clazz) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
      return clazz.getConstructor().newInstance();
  }

但是,您實際上不能在這里使用T (例如<S extends T> )。 由於T是參數類型,因此不能保證BT還是擴展T

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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