プログラマメモ2 - programmer no memo2

javassist メソッドの置き換えは、setBodyで。 2008/02/20


以前、javassistを使っていて、メソッドのふるまいをかえるのにわざわざremoveしてしまってましたが、単純にsetBodyを使って内容をごっそり置き換えたほうがらくですね。

CtClassクラスのremoveMethodを使わずに、CtMethodのsetBodyを使う。

で、setBodyで置き換えるメソッドがもらう引数は、$1,$2,$3....って感じでうけとれます。
それで、staticメソッドでなければ、フィールド変数にはそのまま名前でアクセスできます。
あと、他のクラスにアクセスするためには、パッケージ名まで書かないとだめです。

以下、適当にサンプル。

import a.A;
import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.NotFoundException;

public class TestJavassist {

public static void main(String[] args) throws NotFoundException,
CannotCompileException {
a();
A a = new A();
a.m(17);
System.out.println(a);
}

static void a() throws NotFoundException, CannotCompileException {
ClassPool cp = ClassPool.getDefault();
CtClass cc = cp.get("a.A");
CtMethod method = cc.getDeclaredMethod("m");
method
.setBody("{ b.B b = new b.B(); x= 217 + f; System.out.println(b.xx);}");
cc.toClass();
}
}


package a;

public class A {
private int f = 17;
String s1 = "o_o!";
int x = 100;
int y =300;

public void m(int a){
x += a;
y += a;

}
public String toString(){
return " x:"+x + " y:" + y;
}

}


package b;

public class B {
public int xx= 177;

public int getX(){
return xx;
}
public B() {
}
}


うーん
javassistをプロジェクトに含めておくて、いざというときものすごく役にたつのではないかという予感がふつふつと。

: