Skip to content

其他

参数列表

目前,Javassist不直接支持变量。因此,要使用可变参数创建方法,必须显式设置方法修饰符。但这很简单。假设现在你想做以下的方法:

java
public int length(int... args) { return args.length; }

下面使用Javassist的代码将生成上面所示的方法:

java
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中嵌入的编译器编译的源代码中调用此方法,您必须编写:

java
length(new int[] { 1, 2, 3 });

而不是使用变量机制调用这个方法:

java
length(1, 2, 3);

J2ME

如果为J2ME执行环境修改类文件,则必须执行预验证。预验证基本上是生成堆栈映射,这类似于JDK 1.6中引入J2SE的堆栈映射表。只有当Javassist .bytecode. methodinfo . dopreverify为真时,Javassist才维护J2ME的堆栈映射。

您还可以为修改后的方法手动生成堆栈映射。对于由CtMethod对象m表示的给定方法,您可以通过调用以下方法生成堆栈映射:

java
m.getMethodInfo().rebuildStackMapForME(cpool);

这里,cpool是一个ClassPool对象,它可以通过在CtClass对象上调用getClassPool()来获得。ClassPool对象负责从给定的类路径中查找类文件。要获得所有的CtMethod对象,调用CtClass对象上的getDeclaredMethods方法。

装箱与拆箱

在Java中,装箱和拆箱是语法糖。没有用于装箱或拆箱的字节码。所以Javassist的编译器不支持它们。例如,下面的语句在Java中是有效的:

java
Integer i = 3;

因为装箱是隐式执行的。然而,对于Javassist,必须显式地将值类型从int转换为Integer:

java
Integer i = new Integer(3);

Debug

将CtClass.debugDump设置为目录名。然后,由Javassist修改和生成的所有类文件都保存在该目录中。要停止这种情况,将CtClass.debugDump设置为空。默认值为空。

java
CtClass.debugDump = "./dump";

所有修改后的类文件保存在 ./ dump目录下。

Released under the MIT License.