我是Java的初學者。
如何初始化作為引數接收的型別別串列?我有一個將Class<?>引數作為引數的方法,我想創建一個此型別別的串列。
public List<?> returnList(Class<?> listItemType) {
//create a list of type "listItemType"
//populate the list
//return the list
}
我試過做
List<listItemType> list = new ArrayList<listItemType>()
但 VSCode 顯示listItemType cannot be resolved to a type.
我也嘗試過<? extends listItemType>,<listItemType.getName()>以及下面的代碼,但它們似乎也不起作用。
Object obj = listItemType.getDeclaredConstructor().newInstance();
List<obj.getClass()> = new ArrayList<obj.getClass()>();
uj5u.com熱心網友回復:
如果您使該方法成為具有命名型別引數的泛型方法,它將起作用。例如:
public <T> List<T> returnList(Class<T> listItemType) {
List<T> list = new ArrayList<>();
try {
list.add(listItemType.getConstructor().newInstance());
} catch (ReflectiveOperationException ex) {
// do something
}
return list;
}
請注意,可能有各種例外情況。例如,類可能沒有合適的建構式,建構式可能不可訪問,或者它可能拋出例外。此方法的完整版本應該做一些適當的事情,或者宣告相關的例外,以便它們可以傳播到呼叫者及其他地方。
如果沒有命名型別引數T,則不會將通配符 in 連接List<?>到Class<?>. 所以編譯器不會知道它returnList(Foobar.class)打算回傳一個List<Foobar>.
并且您無法將變數名listItemType用作類名,如List<listItemType>. 這就是為什么您得到“listItemType 無法決議為型別”的原因。變數名和型別名位于不同的 Java 命名空間中。
您的嘗試<? extends listItemType>因同樣的原因而
<listItemType.getName()>失敗,并且因為運算式不是型別而失敗。
考慮這些失敗嘗試的另一種方式是它們使用運行時值(例如 的值listItemType)來進行編譯時型別檢查。這意味著編譯器需要能夠展望未來以了解運行時值將是什么。千里眼不是當前一代 Java 編譯器的特性 :-)。
uj5u.com熱心網友回復:
你需要的是一個通用的方法。
泛型方法允許使用型別引數來表達方法和/或其回傳型別的一個或多個引數的型別之間的依賴關系。
這是一個完整的例子:
public class NewMain {
private static class Foo {
public Foo() {
}
}
public static void main(String[] args) {
// TODO code application logic here
List<Foo> foos = returnList(Foo.class);
System.out.println(foos.get(0));
}
public static <T> List<T> returnList(Class<T> listItemType) {
List<T> list = new ArrayList<>();
try {
T obj = listItemType.getConstructor().newInstance();
list.add(obj);
} catch (Exception ex) {
Logger.getLogger(NewMain.class.getName()).log(Level.SEVERE, null, ex);
}
return list;
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/426111.html
上一篇:如何根據Scala中的另一個引數限制泛型引數的引數型別?
下一篇:使用泛型的工廠模式
