其他
参数列表
目前,Javassist不直接支持变量。因此,要使用可变参数创建方法,必须显式设置方法修饰符。但这很简单。假设现在你想做以下的方法:
public int length(int... args) { return args.length; }
下面使用Javassist的代码将生成上面所示的方法:
CtClass cc = /* target class */;
CtMethod m = CtMethod.make("public int length(int[] args) { return args.length; }", cc);
m.setModifiers(m.getModifiers() | Modifier.VARARGS);
cc.addMethod(m);
参数类型为int…被转换为int[]和Modifier。VARARGS被添加到方法修饰符中。
要在Javassist中嵌入的编译器编译的源代码中调用此方法,您必须编写:
length(new int[] { 1, 2, 3 });
而不是使用变量机制调用这个方法:
length(1, 2, 3);
J2ME
如果为J2ME执行环境修改类文件,则必须执行预验证。预验证基本上是生成堆栈映射,这类似于JDK 1.6中引入J2SE的堆栈映射表。只有当Javassist .bytecode. methodinfo . dopreverify为真时,Javassist才维护J2ME的堆栈映射。
您还可以为修改后的方法手动生成堆栈映射。对于由CtMethod对象m表示的给定方法,您可以通过调用以下方法生成堆栈映射:
m.getMethodInfo().rebuildStackMapForME(cpool);
这里,cpool是一个ClassPool对象,它可以通过在CtClass对象上调用getClassPool()来获得。ClassPool对象负责从给定的类路径中查找类文件。要获得所有的CtMethod对象,调用CtClass对象上的getDeclaredMethods方法。
装箱与拆箱
在Java中,装箱和拆箱是语法糖。没有用于装箱或拆箱的字节码。所以Javassist的编译器不支持它们。例如,下面的语句在Java中是有效的:
Integer i = 3;
因为装箱是隐式执行的。然而,对于Javassist,必须显式地将值类型从int转换为Integer:
Integer i = new Integer(3);
Debug
将CtClass.debugDump设置为目录名。然后,由Javassist修改和生成的所有类文件都保存在该目录中。要停止这种情况,将CtClass.debugDump设置为空。默认值为空。
CtClass.debugDump = "./dump";
所有修改后的类文件保存在 ./ dump目录下。