2017-03-22 109 views
1

我正在處理需要類的檢測的項目。我使用javassist,因爲在我的情況下做儀器非常方便。javassist:重命名類和字段類型

我面臨一個問題,可以使用下面的代碼段來描述:

假設第1類:

public class Class1 { 
    Class2 class2; 
} 

和2類:

public class Class2 { 
    //Code 
} 

而對於一個功能從定義的類中獲取CtClass,並進行一些代碼轉換。

public void testFunction() throws NotFoundException { 
     ClassPool classPlool; 
     classPlool = ClassPool.getDefault(); 
     CtClass ctCls1 = classPlool.getAndRename("Class1", "Class1_V1"); 
     // instrument and load ctCls1 etc. 
     CtClass ctCls2 = classPlool.getAndRename("Class2", "Class2_V1"); 
     // instrument and load ctCls1 etc. 
    } 

至於,我重命名類,所以在Class1領域Class2 class2class Class2類型,但該類被重命名爲Class2_V1。我想將字段類型也從LClass2重命名爲LClass2_V1

ctCls1是:[email protected][changed public class Class1_V1 fields=Class1_V1.class2:LClass2;, [email protected][public Class1_V1()V], methods=]

PS:我已經加載的不同儀器類兩個版本,所以這是在我的情況的最佳途徑。此外,我已經搜索了這個問題,但沒有解決方案來解決它,例如this link描述了重命名字段,但沒有鍵入。

+0

請注意,我總是追加「_V1」或「_V2 」。所以,如果你幫我重命名'LClass1_V1'或'LClass1_V2'就足夠了。 – Aadarsh

+0

你不能完全刪除該字段,然後添加一個新的字段與新的名稱和新的類型? – Nicholas

+0

我可以,但刪除然後添加並使用'setType()'沒有區別 – Aadarsh

回答

1

根據Javassistdocumentation

一類新的可被定義爲現有類的副本。下面的程序做的是:

ClassPool pool = ClassPool.getDefault(); 
CtClass cc = pool.get("Point"); 
cc.setName("Pair"); 

該程序首先獲得用於類Point的CtClass對象。

然後它調用setName()給這個CtClass對象一個新的名字Pair。

在此調用之後,由CtClass對象表示的類定義中的類名定義的所有類名都會從點對點變爲對。類定義的另一部分不會改變。

編輯: 爲了在一個類中重命名字段類型,你可以瀏覽類,並通過Javassist類型得到它CtField

ClassPool pool = ClassPool.getDefault(); 
CtClass cc = pool.get("Class1"); 
CtField cf = cc.getField("class2NameIntoClass1"); 
CtClass cc2 = cf.getType(); 
cc2.setName("Class2NewName"); 
+0

我正在重命名'class2',但'class1'有一個'class2'類型的字段,您所指的方法不能重命名'class1'中的類型。 – Aadarsh