あやみつさんの覚書き

メモや覚書きなど

Visitorを使って既存のクラスに新規メソッドを追加する

言語はJavaでASM4.0

今回は既存のクラスに新しくメソッドを追加する。
検索して解決策をみつけたのでメモ。
SampleClassに新しく"public void foo() {}"を追加する。

おおまかな流れ

// 元のファイル
public class SampleClass {
	
	void f() {}
	
}
// org.objectweb.asm.Opcodes内のstaticなフィールドを参照できる前提

public byte[] transform(byte[] bytes) {
	ClassReader cr = new ClassReader(bytes);
	ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
	ClassVisitor cv = new ClassVisitor(ASM4, cw) {
		@Override
		public void visitEnd() {
			// メソッドを新しくつくる
			// ACC_PUBLICの部分を変えるとアクセサが変わる
			MethodVisitor mv = cv.visitMethod(ACC_PUBLIC, "foo", "()V", null, null);
			mv.visitMaxs(0, 0);// ClassWriterのCOMPUTE_MAXSのフラグをたてているので勝手に計算してくれる
			
			super.visiteEnd();
		}
	};
	
	cr.accept(cw, 0);
	return cw.toByteArray();
}
// 書き換え後
public class SampleClass {
	
	void f() {}
	
	public void foo() {}
	
}

メソッドを追加したいときはvisitEndをいじる。

参考URL: