天天看点

JVM Class字节码之三-使用BCEL改变类属性

之前对class文件中的常量池,method的字节码指令进行了说明。

jvm class详解之一

jvm class详解之二 method字节码指令

现在我们开始实际动手,使用bcel改变字节码指令,对class文件进行功能扩充。

先介绍下bcel全程apache byte code engineering library,bcel 每项内容操作在jvm汇编语言的级别

这个case我们需要给programmer类做功能扩展,programmer 职责进行了变化,除了要coding以外,在每次coding之前需要先做plan,所以需要在do coding信息输出之前输出 "dobcelplan..." 信息。

demo

期望效果

针对我们的期望结果我们需要做以下三点

增加一个dobcelplan方法

在docoding方法中调用dobcelplan方法

在常量池中加入方法的声明,常量等其它使用到的变量和方法。

工程先引入bcel的依赖pom中追加即可

第一个参数的去路径类名

第二个参数是方法名称

第三个方法返回类型 ()v 是void类型

方法返回类型描述参考

JVM Class字节码之三-使用BCEL改变类属性

因为有system.out.println("dobcelplan")语句 

dobcelplan中的system.out 变量和println方法再docoding中已经使用所有已经在常量池中了

JVM Class字节码之三-使用BCEL改变类属性

注意这里需要记录追加方法和filed的index后面需要使用。

调用system.out变量和println方法 具体的字节码指令参数 上一节内容有说明 参考上一节文档 jvm class详解之二 method字节码指令

JVM Class字节码之三-使用BCEL改变类属性

其中17,25都是常量池的引用参见下图,将原先的programmer类编译后使用javap -versobse xxx.class 可以查看常量池信息。

JVM Class字节码之三-使用BCEL改变类属性

stringindex 是引用第三步追加常量池string field sobcelplan

方法的声明并追加到classgen中。

这样dobcelplan方法就追加成功了。接下来我们需要找到docoding方法,在方法中追加dobcelplan的调用。

instructionlist 是当前方法中的字节码指令,我们append了两个指令aload和invokespecial。实现dobcelplan的调用。

将修改后的字节码输出来看下,使用jd打开ok

JVM Class字节码之三-使用BCEL改变类属性

可以看到经过编辑后的class文件输出结果同我们预期的是一样的

done!