2012-11-13 34 views
0

在通用方法中,我似乎無法在運行時訪問方法的通用類型(錯誤:無法從類型變量中選擇)。從通用創建類對象

public <A> A get(Animal a) { 
    Class ac = a.getClass(); 
    if(ac.isAssignableFrom(A.class)) { // <- not working! 
     return (A) a; 
    } else { 
     // error handling 
    } 
} 

我之所以這樣做是爲了能夠安全地轉換的東西,如:

Animal a = new Dog(); 
Dog d = get(a); // <- OK 
Cat c = get(a)  // <- incompatible types, caught by else block 

我發現後從超過9年前完全相同的問題: https://forums.oracle.com/forums/thread.jspa?threadID=1184291

在那裏,解決這個問題的想法是在構造函數中提供一個Class對象,並使用這個變量來檢查它是否可賦值。這似乎是一個非常愚蠢的解決方案,因爲你可以把任何類放在那裏,所有漂亮的類型檢查是沒用的...

所以,同樣的問題:爲什麼應該在構造函數中提供<any>.class<A>是完全已知的?我如何訪問<A>的實際類型?


發現了一個很醜的解決方案:

public <A> A get(Animal a, Class<A> clazz) { 
    // same as above... 
} 

所以,現在你必須提供一個Class,但你可以在這裏插入的唯一有效類是你的返回類型。但至少現在它是類型安全的。

只是完全不方便......

回答

4

出乎你的說法,A類型是運行時知道。請參閱有關type erasure的文檔以瞭解更多詳情。

簡而言之,運行時知道您有一個類型爲Whatever的對象。但是,如果沒有明確提供信息,則無法區分Whatever<A>Whatever<B>。這就是爲什麼建議您提供一個類對象。注意這與編譯階段不同,在編譯階段中已知完整類型信息。

+0

會發生什麼? – 11684

+0

它仍然會調用正確的方法等。它只是缺少的通用信息 –

+0

仍然很無用,因爲我必須將類型聲明爲參數,但調用方不會將_actual_返回類型作爲參數進行綁定,因此類型安全性是不存在的...... – Klamann