[英]How to make a reference to a class using a string of the same name
假設我有兩個實現接口A的類Foo和Bar。我想要創建一個Foo或Bar的ArrayList。 在命令行參數中,用戶必須輸入Foo或Bar,以確定他們嘗試創建ArrayList的對象。
所以:
public static void main(String [] args){
String type = args[0];
ArrayList<type> list = new ArrayList<type>();
}
如何從字符串類型轉到類Foo或Bar的引用,以便它正在執行
ArrayList<Foo> list = new ArrayList<Foo>();
or
ArrayList<Bar> list = new ArrayList<Bar>();
這樣我可以做到以下幾點:
for(int i = 0 ; i < list.size() ; i++){
list(i).doSomething();
//doSomething is a function in interface A that Foo and Bar are required to implement
}
要清楚,我不想要類似的東西
if (type.equals("Foo")) list = ArrayList<Foo>();
我希望能夠使用與類型相同的任何有效類創建一個ArrayList。
編譯器需要知道類型,聽起來你想將類型視為運行時變量而不是編譯時事實。
檢查在運行時獲取泛型類 。 它本質上要求相同的東西,你將獲得有關使用反射的可能的解決方案解決方案的良好信息。
這在Java中是不可能的。 您可以使用反射檢索類型名稱,但無法動態創建泛型類型。
原因是泛型類型僅在編譯時存在,並且編譯器使用它來強制執行靜態類型安全性。 在運行時,通用信息被丟棄,因此在您所要求的內容中(在當前的Java哲學中)甚至沒有意義。 在運行時,泛型類型已轉換為Object
,編譯器在必要時具有替換的類型安全轉換。
使用Class.forName(String classNameWithPath)
方法 - 它會做你想要的。
這里有一個例子 - “Class.forName()”和“Class.forName()。newInstance()”之間有什么區別?
將數組列表聲明為ArrayList<A>
。 這樣它就可以存儲Foo和Bar對象,因為它們都實現了接口A.
您可以維護實現該接口的所有可能類型的列表,然后迭代它們的類型,直到找到與輸入字符串匹配的類型。 除此之外,我認為你在Java中做這件事會遇到麻煩。
public class ForNameTest {
public static void main(String[] argv) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
java.util.ArrayList<String> arrayList = null;
try {
Class<?> createdClass = Class.forName("java.util.ArrayList<java.lang.String>");
arrayList = (java.util.ArrayList<String>) (createdClass.newInstance());
arrayList.add("ABC");
System.out.println("First case " + arrayList.toString());
}
catch (ClassNotFoundException e) {
System.out.println("Exception in first case: " + e.toString());
}
try {
Class<?> createdClass = Class.forName("java.util.ArrayList");
arrayList = (java.util.ArrayList<String>) (createdClass.newInstance());
arrayList.add("ABC");
System.out.println("Second case " + arrayList.toString());
}
catch (ClassNotFoundException e) {
System.out.println("Exception in second case: " + e.toString());
}
}
}
輸出:
C:\JavaTools>javac ForNameTest.java
Note: ForNameTest.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
C:\JavaTools>java ForNameTest
Exception in first case: java.lang.ClassNotFoundException: java.util.ArrayList<java.lang.S
tring>
Second case [ABC]
(不確定這證明了什么 - 你仍然不能聲明你的ArrayList是變量(vs <?>
)類型。但它是,FWIW。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.