【简述】

Javassist是一个开源的java字节码操作工具,主要是对已经编译好class文件进行修改和处理,可以直接检查、修改、创建 java类。

【javassist实例】

package com.javassist;

import javassist.*;

import java.io.File;
import java.io.FileOutputStream;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier; /**
* Created by cuixinjie on 2018/9/7.
*/
public class JavassistTest { public static void main(String[] args) throws Exception {
//ClassPool:ctClass对象的容器
ClassPool pool = ClassPool.getDefault();
//通过ClassPool深沉给一个public的新类 User.java
CtClass ctClass = pool.makeClass("com.javassist.User"); //添加属性,首先添加age属性:private Integer age;
CtField ageField = new CtField(pool.getCtClass("java.lang.Integer"), "age", ctClass);
ageField.setModifiers(Modifier.PRIVATE);
ctClass.addField(ageField); //添加属性,其次添加phone属性:private String phone;
CtField phoneField = new CtField(pool.getCtClass("java.lang.String"), "phone", ctClass);
phoneField.setModifiers(Modifier.PRIVATE);
ctClass.addField(phoneField); //为age和phone添加getXxx/setXxx方法
ctClass.addMethod(CtNewMethod.getter("getAge", ageField));
ctClass.addMethod(CtNewMethod.setter("setAge", ageField));
ctClass.addMethod(CtNewMethod.getter("getPhone", phoneField));
ctClass.addMethod(CtNewMethod.setter("setPhone", phoneField)); //添加构造方法
CtConstructor ctConstructor = new CtConstructor(new CtClass[]{}, ctClass);
//为构造方法添加方法体
StringBuffer buffer1 = new StringBuffer();
//注意:this.age = ($w)18这里加上$w,因为age是Integer类型,是一个包装类,$w代表一个包装类型
buffer1.append("{\nthis.age = ($w)18;\nthis.phone = \"15966668888\";\n}");
ctConstructor.setBody(buffer1.toString());
//把构造方法添加到新的类ctClass中
ctClass.addConstructor(ctConstructor); //添加自定义方法
CtMethod ctMethod = new CtMethod(CtClass.voidType, "printInfo", new CtClass[]{}, ctClass);
//为自定义的方法设置方法体
StringBuffer buffer2 = new StringBuffer();
buffer2.append("{\nSystem.out.println(\"I can get Alibaba's offer!\");\n");
buffer2.append("System.out.println(\"my age is \"+age);\n");
buffer2.append("System.out.println(\"my phone is \"+phone);\n");
buffer2.append("}");
ctMethod.setBody(buffer2.toString());
ctClass.addMethod(ctMethod); //生成一个Class对象
Class<?> clazz = ctClass.toClass();
Object instance = clazz.newInstance();
//反射 执行方法
Method method = instance.getClass().getMethod("printInfo", new Class[]{});
method.invoke(instance,null); // 把生成的class文件写入文件
byte[] byteArr = ctClass.toBytecode();
FileOutputStream fos = new FileOutputStream(new File("./User.class"));
fos.write(byteArr);
fos.close();
}
}

【运行结果】

06_javassist的更多相关文章

随机推荐

  1. Navicat 导出sql文件和导入sql文件

    1.导出sql文件 (1)选择需要导出数据库表,右击--->转储为sql文件---->结构和数据 (2)会弹出如下界面,采用默认的数据表名,点击确认即可. 2.导入sql文件 (1)点击表 ...

  2. StringBuffer与StringBuilder的区别比较

    关于AbstractStringBuilder 首先通过查看源码发现,StringBuffer与StringBuilder都继承自AbstractStringBuilder抽象类.而AbstractS ...

  3. codeforces1137B kmp(fail的妙用)

    题目传送门 题意:给出$s$和$t$两个串,让你构造出一个答案串,使得答案串中的01数量和s一样,并且使$t$在答案串中作为子串出现次数最多. 思路: 要想出现的次数尽可能多,那么就要重复的利用,哪一 ...

  4. Git版本回退和撤销修改

    版本回退: 在实际工作中,我们会不断对文件进行修改,然后不断提交修改到版本库里,一旦你把文件改乱了,或者误删了文件,还可以从最近的一个commit恢复,然后继续工作,而不是把几个月的工作成果全部丢失. ...

  5. Android中判断service是否在运行

    /** * 判断服务是否开启 * * @return */ public static boolean isServiceRunning(Context context, String Service ...

  6. ionic3 pop到指定页面

    this.navCtrl.getViews().forEach(element => { if(element.name == 'JiecheHomePage'){ this.navCtrl.p ...

  7. jQuery练习 | 模态对话框(添加删除)

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. Jmeter调试脚本之断言

    前言: jmeter中有个元件叫做断言(Assertion),它的作用和loadrunner中的检查点类似: 用于检查测试中得到的响应数据等是否符合预期,用以保证性能测试过程中的数据交互与预期一致. ...

  9. ES6基本语法之let和const

    1.var可以重复声明 var a = 12; var a = 5; alert(a) //5 2.var无法限制修改 如:PI = 3.1415: 3.var没有块级作用域 { } 像: if(){ ...

  10. ubuntu下安装Sublime Text2

    1.下载Sublime Text2官网下载地址:http://www.sublimetext.com 2.安装Sublime Text2解压即可使用,如linjiqin@ubuntu:~$ sudo ...