使用javassist生成新类

来源:互联网 发布:c语言 绝对值 double 编辑:程序博客网 时间:2024/06/05 11:08

1、简介

javassist是一个开源的分析、编辑和创建java字节码的类库。不需要了解虚拟机指令,就能动态生成类或者改变类的结构。

2、下载

(1)下载链接http://www.csg.ci.i.u-tokyo.ac.jp/~chiba/javassist/

(2)使用的版本是javassist-3.18.0-GA。

3、实验

此实验的目的是通过javassist生成一个新类Emp.java

(1)生成的目标类Emp.java

package com.study.javassist;public class Emp {private String ename;private int eno;public Emp(){ename="yy";eno=001;}public String getEname() {return ename;}public void setEname(String ename) {this.ename = ename;}public int getEno() {return eno;}public void setEno(int eno) {this.eno = eno;}//添加一个自定义方法public void printInfo(){System.out.println("begin!");System.out.println(ename);System.out.println(eno);System.out.println("over!");}}

(2)主类GenerateNewClassByJavassist.java

package com.study.javassist;import java.io.File;import java.io.FileOutputStream;import java.lang.reflect.Modifier;import javassist.ClassPool;import javassist.CtClass;import javassist.CtConstructor;import javassist.CtField;import javassist.CtMethod;import javassist.CtNewMethod;/** *使用javassit动态生成一个java类 * @author yy * @version 1.0 *  */public class GenerateNewClassByJavassist {public static void main(String[] args) throws Exception{//ClassPool:CtClass对象的容器ClassPool pool = ClassPool.getDefault();//通过ClassPool生成一个public新类Emp.javaCtClass ctClass = pool.makeClass("com.study.javassist.Emp");//添加字段//首先添加字段private String enameCtField enameField = new CtField(pool.getCtClass("java.lang.String"),"ename",ctClass);enameField.setModifiers(Modifier.PRIVATE);ctClass.addField(enameField);//其次添加字段privtae int enoCtField enoField = new CtField(pool.getCtClass("int"),"eno",ctClass);enoField.setModifiers(Modifier.PRIVATE);ctClass.addField(enoField);//为字段ename和eno添加getXXX和setXXX方法ctClass.addMethod(CtNewMethod.getter("getEname", enameField));ctClass.addMethod(CtNewMethod.setter("setEname", enameField));ctClass.addMethod(CtNewMethod.getter("getEno", enoField));ctClass.addMethod(CtNewMethod.setter("setEno", enoField));//添加构造函数CtConstructor ctConstructor = new CtConstructor(new CtClass[]{}, ctClass);//为构造函数设置函数体StringBuffer buffer = new StringBuffer();buffer.append("{\n")  .append("ename=\"yy\";\n")  .append("eno=001;\n}");ctConstructor.setBody(buffer.toString());//把构造函数添加到新的类中ctClass.addConstructor(ctConstructor);//添加自定义方法CtMethod ctMethod = new CtMethod(CtClass.voidType,"printInfo",new CtClass[]{},ctClass);//为自定义方法设置修饰符ctMethod.setModifiers(Modifier.PUBLIC);//为自定义方法设置函数体StringBuffer buffer2 = new StringBuffer();buffer2.append("{\nSystem.out.println(\"begin!\");\n").append("System.out.println(ename);\n").append("System.out.println(eno);\n").append("System.out.println(\"over!\");\n").append("}");ctMethod.setBody(buffer2.toString());ctClass.addMethod(ctMethod);//为了验证效果,下面使用反射执行方法printInfoClass<?> clazz = ctClass.toClass();Object obj = clazz.newInstance();obj.getClass().getMethod("printInfo", new Class[]{}).invoke(obj, new Object[]{});//把生成的class文件写入文件byte[] byteArr = ctClass.toBytecode();FileOutputStream fos = new FileOutputStream(new File("D://Emp.class"));fos.write(byteArr);fos.close();}}

(3)实验结果

首先打印结果如下:

begin!yy1over!
通过XJad反编译结果如下:

// Decompiled by Jad v1.5.8e2. Copyright 2001 Pavel Kouznetsov.// Jad home page: http://kpdus.tripod.com/jad.html// Decompiler options: packimports(3) fieldsfirst ansi space // Source File Name:   Emp.javapackage com.study.javassist;import java.io.PrintStream;public class Emp{private String ename;private int eno;public String getEname(){return ename;}public void setEname(String s){ename = s;}public int getEno(){return eno;}public void setEno(int i){eno = i;}public Emp(){ename = "yy";eno = 1;}public void printInfo(){System.out.println("begin!");System.out.println(ename);System.out.println(eno);System.out.println("over!");}}

可见,通过javassist可以动态的生成类。

原创粉丝点击