2011-09-12 15 views
6

在我的程序中,我處理類和基本類型。 如果程序發現的一類,它只是將執行下列操作的呼叫的一個:如何用Javassist獲取原始類型的類?

  • Class.forName(classname)
  • cc.toClass()其中ccCtClass

一個實例。然而,如果它發現一個基本類型,事情變得更糟:

  • Class.forName不可用,它不能使用與原始類型。
  • cc.toClass()回報null

它可以從原始類型的包裝類調用TYPE場,但我怎麼能與反思辦呢?

這裏是我的代碼:

CtClass cc;//Obtained from caller code 
Class<?> classParam; 
if (cc.isprimitive()) { 
    classParam= ?? // How can I get TYPE field value with reflection ? 
} else { 
    String nomClasseParam = cc.getName(); 

    if (nomClasseParam.startsWith("java")) { 
     classeParam = Class.forName(nomClasseParam); 
    } else { 
     classeParam = cc.toClass(); 
    } 
} 

了Javassist 3.12.0.GA

編輯: 我已經張貼在下面的anwsers the solution I chose。 無論如何,我打勾Tom's answer

+2

這個問題肯定會有幫助:[boolean.class?](http://stackoverflow.com/questions/1019208/boolean-class) –

+0

@Andreas_D沒多少,因爲我想用java反射來執行調用。 – Stephan

+0

,但是當我們反映方法和構造函數時,我們可以使用'boolean.class','int.class'等等作爲'Class'對象。 –

回答

5

在我看來,你可以投cc到其子類CtPrimitiveType

如果你想要一個包裝器,你可以使用方法getWrapperName來獲取適當包裝器的類名稱。您可以像往常一樣使用Class.forName將該名稱轉換爲Class對象。但是,我不認爲你想要一個包裝,所以這沒有幫助。

相反,我想你想getDescriptor,隨後費力硬編碼的switch語句:

switch(descriptor) { 
    case 'I': classParam = int.class; break; 
    // etc 
} 

類似的東西確實應該是Javassist進行。但據我所知,事實並非如此。

+0

'getDescriptor'爲什麼不,編寫儘管很費力的switch語句... – Stephan

+0

最後,我使用'getWrapperName'並且避免必須編寫一個switch語句 – Stephan

+0

假設只有八種基本類型,它不會很難寫。 –

1

您可以爲基元的對象包裝器(例如用於基元int的整數)執行Class.forName。 Java支持自動裝箱,所以你可以在對象包裝器和原始對象之間進行交換。

我假設您正在使用JavaAssist的CtClass。 如果cc是一個原始的,我認爲它將是一種CtPrimitiveType(需要確認),在這種情況下,你可以投擲並調用getWrapperName()來獲得包裝類。

+1

在反思的世界中不是真實的。 :( – dacwe

+0

你是對的,Java支持自動裝箱,但是我操作的類是由Javassist動態生成的,生成的類有一個帶int參數的方法,如果我給他java,classloader就無法找到這個方法。 'Class.forName'中的lang.teger'參數。 – Stephan

+0

@dawce呃,我不知道那個:(應該用更多的反射來玩,Stephan看起來像湯姆的答案應該可以工作 – momo

3

基於從湯姆和MOMO的反應,這裏是我想出瞭解決方案:

CtClass cc; //Obtained from caller code 
Class<?> classParam; 

if (cc.isprimitive()) { 
    classParam = Class.forName(((CtPrimitiveType)cc).getWrapperName()); 
    classParam = (Class<?>)classParam.getDeclaredField("TYPE").get(classParam); 
} else { 
    String nomClasseParam = cc.getName(); 

    if (nomClasseParam.startsWith("java")) { 
     classeParam = Class.forName(nomClasseParam); 
    } else { 
     classeParam = cc.toClass(); 
    } 
} 

我打電話CtPrimitiveType#getWrapperName方法,然後我用類型字段,以獲得原始類型的類。我也避免寫一個switch語句。

感謝您的幫助球員。