簡體   English   中英

如何使用相同名稱的字符串引用類

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

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