2014-09-05 69 views
0

只有在運行時我在通過了完整的類名(即「com.firm.me.MyClass」)需要傳遞一個泛型類的類型參數的基礎上,合格的類名稱的字符串

我需要實例化一個通用類,定義爲:

Class A <T> 
{ 
} 

其中「T」是與傳入的全限定類名稱關聯的類型。

我有以下幾點:

Class <?> clazz = Class.forName ("com.firm.me.MyClass"); 

我想(從邏輯上說)有類似的東西..

A <clazz> myInstance = new A <clazz>; 

上面的使用位置「clazz中」的會引起以下錯誤:

「clazz無法解析爲類型」。

我該如何做我想做的事(邏輯上)。

非常感謝。

+0

由於類型擦除'A myInstance'無論如何都會解析爲'A myInstance',所以即使你得到了這個工作,你也不會從中受益。你究竟想要做什麼? – Thomas 2014-09-05 09:22:18

+0

我有一個序列化的持久數據存儲。可能有幾家商店,並且每個商店內的所有對象都是相同類型的。我在「A類」上面給出的類例子實例化了我的持久/提取類。我想要做的是讓用戶輸入保存在其數據存儲中的數據類型的類名,以便我可以使用通用的基於命令行的應用程序,然後可以使用該應用程序來檢索其數據。我想基於它們從命令行 – user1151685 2014-09-05 09:49:29

+0

@ user1151685輸入的完全限定類名實例化persist/retriever實例,您應該在類A中聲明一個成員變量,並通過構造函數初始化它。讓我知道下面的解決方案解決您的問題 – 2014-09-05 10:02:30

回答

4

你不能在Java中做這樣的事情。閱讀關於類型erasure

除了類型擦除的問題 - 這使得在任何情況下都不可能 - 你根本不能保證T有一個暴露的,無參數的構造函數!

傳統的解決方法是傳遞工廠對象,這些工廠對象提供可用於獲取T對象的方法。一個簡單的例子是

interface Factory<T> { 
    T create(); 
} 

,然後你的類可以得到一個Factory<T>,並呼籲create()它來獲得更多的T's。更復雜的示例可能需要額外的參數,例如create()方法或重載。

0

您應更改爲Class A到這樣的事情: -

class A<T> { 

    Class<T> clazz; 

    public A(Class<T> clazz) { 
     this.clazz = clazz; 
    } 

    public static void main(String[] args) throws ClassNotFoundException { 
     @SuppressWarnings("unchecked") 
     Class<com.firm.me.MyClass> clazz = (Class<MyClass>) Class 
       .forName("com.firm.me.MyClass"); 
     A<MyClass> myInstance = new A<MyClass>(clazz); 
    } 
} 

只要創建一個構造函數,需要一個類object.In這樣一來,不僅是你在運行時得到正確的類對象,可以使用泛型以您想要的方式處理參數化對象

0

在Java中,必須在編譯時解析泛型類型。事實上,由於着名的類型擦除(請檢查:Get generic type of class at runtime),它們在運行時幾乎無法訪問。

檢查大約同樣的問題這個問題:Dynamic Generic Typing in Java

你應該堅持舊的非類型AA<Object>,在那裏你可能包括像 http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#cast%28java.lang.Object%29 http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#isAssignableFrom%28java.lang.Class%29

一些運行時檢查
0

泛型是隻在編譯時用於編譯時類型檢查。因此,如果在編譯時未知類型參數,則不起任何作用。

相關問題