[英]How can I instantiate a class instance in java with generics?
如何使用泛型實例化Java中的類實例?
我試圖從XML文件讀取數據,然后實例化對象,以便可以將對象的其他屬性(從XML文件讀取)添加到對象中。 我認為最簡單的方法(這樣我就不必讀取類方法的名稱並查找設置方法)將是使用構造函數中的所有值實例化該對象。
我試圖做這樣的事情,所以我需要有這樣的事情: T obj = new Object()
但要獲取對象類
private static final boolean string_field = true;
private static <T> T getObject(Element e, String[] fieldNames, boolean[] fieldTypes) {
Object[] values = new Object[fieldNames.length];
for (int i=0; i<fieldNames.length; i++) {
values[i] = (fieldTypes[i]==string_field)? getStringValue(e, fieldNames[i])
: getIntegerValue(e, fieldNames[i]);
}
return new T(values);
}
謝謝你的建議。
編輯:
這是我更新的代碼(未經測試):
public static <T> List<T> populateObjectList(Document xmlDoc, String tagName,
Class clazz, String[] fieldNames, Class[] fieldTypes) {
List<T> objList = new ArrayList<T>();
NodeList nl = xmlDoc.getElementsByTagName(tagName);
if (nl!=null && nl.getLength()>0) {
for (int i=0; i<nl.getLength(); i++) {
Element e = (Element) nl.item(i);
T t;
try {
t = getObject(e, clazz, fieldNames, fieldTypes);
objList.add(t);
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
} catch (IllegalArgumentException ex) {
} catch (InvocationTargetException ex) {
} catch (NoSuchMethodException ex) {
}
}
}
return objList;
}
private static <T> T getObject(Element e, Class clazz, String[] fieldNames, Class[] fieldTypes)
throws InstantiationException, IllegalAccessException, IllegalArgumentException,
InvocationTargetException, NoSuchMethodException {
Object[] initargs = new Object[fieldNames.length];
for (int i=0; i<fieldNames.length; i++) {
initargs[i] = (fieldTypes[i].getName().equals("int"))?
getIntegerValue(e, fieldNames[i])
: getStringValue(e, fieldNames[i]);
}
return (T) clazz.getConstructor(fieldTypes).newInstance(initargs);
}
我發布了這個信息,以便你們中的一些人了解我正在嘗試做的事情。
再次感謝大家的建議。
您不能實例化泛型類型。 Java泛型具有一個令人討厭的特性,稱為類型擦除 ,它基本上意味着JVM在運行時不知道泛型類或方法使用了哪種類型。 這是為了向后兼容通用類的通用版本,例如集合。
您可以做的是將Class<T> clazz
添加到參數列表,然后用以下方法替換方法的結尾:
Class<?>[] paramTypes = new Class[values.length];
for (int i = 0; i < paramTypes.length; i++) {
paramTypes[i] = values[i].getClass();
}
return clazz.getConstructor(paramTypes).newInstance(values);
如果該類沒有構造器以正確的順序采用正確的類型和數量的參數,則將引發異常。
CAVEAT:僅當構造函數的參數類型與對象類型完全相同時 ,此方法才有效。 例如,如果values
包含{ "Hello", new Integer(2) }
,那么它將僅找到帶有簽名SomeClass(String, Integer)
的構造函數,而不是帶有簽名SomeClass(Object, Object)
的構造函數。
您甚至怎么知道T
包含一個采用單個Object[]
參數的構造函數? 解決此問題的方法是傳入一個抽象工廠。
interface ThingFactory { // Choose an appropriate name.
T create(Object[] values);
}
private static <T> T getObject(
ThingFactory<T> factory, Element e, String[] fieldNames, boolean[] fieldTypes
) {
...
return factory.create(values);
}
現在, T
甚至可能沒有一個很奇怪的Object[]
構造函數。 T
可能是抽象類型。 工廠可能會根據參數返回不同的類型。 也許有時這些產品是可以緩存的不可變對象。
您不能執行new T()
因為在運行時, T
實際上只是Object
。 編譯器使用泛型進行類型檢查(例如,您不能將Integer
放入List<String>
),但隨后會將泛型信息丟棄。 該方法針對所有類型的參數都有一個已編譯的副本,因此它無法知道您希望實例化哪種類型。
閱讀有關類型擦除的更多信息。
我真的看不到您的問題,無法使用obj.getClass嗎?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.