2012-05-29 75 views
9

我想要使泛型函數返回XML文檔的對象表示(使用JAXB)。我需要將「class」對象傳遞給JAXBContext構造函數,但是我怎麼能從T中獲取它?從泛型類型獲取「類」對象T

public <T> readXmlToObject(String xmlFileName, T jaxbClass) { 
    JAXBContext context = JAXBContext.newInstance(T.class); // T.class - here error, how to get it? 
    ....... 
} 
+1

搜索 '類型擦除' :-) –

回答

13

改爲傳遞類對象,這很容易。

public <T> T readXmlToObject(String xmlFileName, Class<T> jaxbClass) { 
     JAXBContext context = JAXBContext.newInstance(jaxbClass); // T.class - here error, how to get it? 
     Object o = context.createUnmarshaller().unmarshal(new File(xmlFileName)); 
     return jaxbClass.cast(o); 
} 

這裏的想法是,既然你不能提取對象類型參數,你必須圍繞做另一種方式:先從類,然後操作對象相匹配的類型參數。

+0

(我不認爲'?extends'在這裏買東西。) –

+0

@ TomHawtin-tackline你是對的。 – biziclop

3

您不能在運行時獲得類。 Java使用類型安全擦除實現泛型,這意味着對泛型類型的理解僅適用於通過編譯。如果您想獲得其課程,您必須在運行時間對實際對象進行調試。

+2

-1錯!該類正在傳入。問題出在方法簽名 – Bohemian

+1

感謝您的輸入。正如所寫,它不會工作,但我看到你的意見,改變輸入類而不是噸。這將是沒有問題的。如果由於Java的不良泛型impl而不是一個問題,那將是很好的。 –

+0

我刪除了我的downvote - 你的回答不是*那*錯誤:) – Bohemian

1

看看this SO answer

基本上,類型T在運行時不可用 - Java泛型必須遵循erasure by the compiler

幸虧你已經有你的類的實例,所以你可以從那裏類型的信息:

public <T> readXmlToObject(String xmlFileName, T jaxbClass) { 

    // if jaxbClass is an instance of the data object, you can do this: 
    JAXBContext context = JAXBContext.newInstance(jaxbClass.getClass()); 

    // alternatively if jaxbClass is an instance of the Class object: 
    JAXBContext context = JAXBContext.newInstance(jaxbClass); 
    // ...... 
} 
+0

-1完全不會工作。 'jaxbClass.getClass()'將返回'Class.class'。而你也錯了 - 擦除在這裏不是問題,因爲這個類正在被傳入。 – Bohemian

+0

啊 - 我認爲它是受限於T而不是類它是類的一個實例(如果你得到我的漂移......) –

+0

我確實得到你,但認爲這是他的問題 - 他編碼的參數類型錯誤。他*不是*傳入'T',因爲在通話之後他不會有'T'的實例,但他可以通過'Class '的實例。我承認我會通過參數名稱'jaxbClass',這非常強烈地表明它是'class'。 – Bohemian

1

嘗試通過類本身,像這樣

public <T> readXmlToObject(String xmlFileName, Class<T> class) { 
6

別不要聽別人的話......你可以得到它。

jaxbClass參數的類型簡單地更改爲Class<T>

public <T> T readXmlToObject(String xmlFileName, Class<T> jaxbClass) { 
    JAXBContext context = JAXBContext.newInstance(jaxbClass); 
    ....... 
} 
0
public class XYZ<T> { 
    ... 
    private Class<T> tClass;  
    ... 
    public <T> readXmlToObject(String xmlFileName) { 
     JAXBContext context = JAXBContext.newInstance(tClass); 
     ... 
    } 
    ... 
} 
+0

我不認爲這會工作,因爲tClass沒有被初始化,並且你最終將一個空值傳遞給「JAXBContext.newInstance(..)」調用。 –

+0

你說得對,@ go-rose-hulman。 –

+1

在我的代碼中,我是這樣做的:private Class entityClass; final ParameterizedType type =(ParameterizedType)getClass()。getGenericSuperclass(); entityClass =(Class )type.getActualTypeArguments()[0]; –