简单的说,字节码工程库就是用于处理Java字节码的类库。运用字节码工程库,开发人员可以方便地分析,创建和操作Java类文件(以.class结尾的文件,或者说前四个字节是0xCAFEBABE的文件)。字节码工程会发生在编译之后或者类装载器装载类之前,一些技术使用节码操作优化或提高现存class的性能,另一个些技术却使用节码操作来使现存的class更易于使用或者用来避免笨重的代码生成。类通过一些包含函数,成员以及字节码指令等标识符信息的对象来表示一个类。
下面我使用Javassit提供的一些API来展示字节码工程库的特性。
1. ClassPool pool = ClassPool.getDefault();
2. CtClass nodeClass = pool.get("test.sql.DMLStatementNode");
3. System.out.println(nodeClass.getSuperclass().getName());
4. nodeClass.setSuperclass(pool.get("test.sql.Node"));
5. nodeClass.writeFile();
ClassPool对象是CtClass的工厂,它在指定的类路径里搜索每一个类文件,并为一个搜索到的类文件建立一个单例CtClass对象,get方法根据指定的类名返回用于描述该类的CtClass对象。在第三行打印出DMLStatementNode的父类,在第四行将其父类改为Node,然后将改变后的结果写回类文件。如果要在运行时直接使用改变后的类,而不将其写入类文件。只需将第五行改为
5. Class class = nodeClass.toClass();
6. Node node = (DMLStatementNode)nodeClass.newInstance();
同样,我们也可以重新定义出一个新的类出来:
1. ClassPool pool = ClassPool.getDefault();
2. CtClass cc = pool.makeClass("test.sql.DDLStatementNode");
3. CtMethod m = CtNewMethod.make(“public void printSubTree(){System.out.println(\“print sub tree\”);}”);
4. cc.addMethod(m);
5. Class class = cc.toClass();
6. DDLStatementNode node = (DDLStatement)class.newInstance();
7. node.printSubTree();
下面是几个比较著名的字节码工程库,每种字节码工程的使用方法不一样,参看各自的文档。
Javassit(http://www.csg.is.titech.ac.jp/~chiba/javassist/)
BCEL(http://jakarta.apache.org/bcel/)
ObjectWeb ASM(http://asm.objectweb.org/)
可以从http://java-source.net/open-source/bytecode-libraries获取开源字节码工程库的有关信息