使用javassist生成新类

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.java
		CtClass ctClass = pool.makeClass("com.study.javassist.Emp");
		
		//添加字段
		//首先添加字段private String ename
		CtField enameField = new CtField(pool.getCtClass("java.lang.String"),"ename",ctClass);
		enameField.setModifiers(Modifier.PRIVATE);
		ctClass.addField(enameField);
		
		//其次添加字段privtae int eno
		CtField 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);
		
		//为了验证效果,下面使用反射执行方法printInfo
		Class<?> 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!
yy
1
over!
通过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.java

package 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可以动态的生成类。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值