【简述】

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. Maximum call stack size exceeded

    写vue时报了如下错误 Maximum call stack size exceeded 栈溢出,因为在调用函数时使用了递归调用,而且没有写跳出条件,导致了该错误

  2. python之类与对象(3)

    4. 类的初始化函数__init__(): 本章参考:https://blog.csdn.net/hellocsz/article/details/82795514  原作者: hellocsz 总结 ...

  3. mfix18.1.1的cmake编译相关问题

    今天把mfix-18.1.1\model\monitors里的文件拷到当前工作目录,进行修改编译,发现修改后运行发现并没有出现任何修改后的效果,发现这几个文件只有在原始目录里修改的才起作用,拷贝到当前 ...

  4. Ntp客户端

    function parseMsg (buffer) { if (buffer.length !== 48) return; const pkt = {}, now = new Date().getT ...

  5. win10操作系统系统,小米路由器,小米3 的问题

    注意 , 置顶 单独一篇 : { win10  局域网共享 小米路由器,操作盘太卡 } 开发中用专业版 , 别用家庭版 比如有远程桌面程序 和 HV 虚拟机 查看激活信息 和 是不是永久激活 参考 h ...

  6. Android自动化之AccessibilityService

    简介demo示例说明Manifest声明AccessibilityService的XML配置文件创建继承自AccessibilityService的服务类MainActivity检测服务是否开启UiA ...

  7. 用vue建新项目的过程---在工作中

    1.git clone 项目地址 2.如果没装vue-cli,就先装下vue-cli  (如果报错可能是没按管理员身份安装) 3.vue init webpack 项目名 4.安装项目依赖 npm i ...

  8. 【C语言】-指向一维数组元素的指针

    本文目录 一.用指针指向一维数组的元素 二.用指针遍历数组元素 三.指针与数组的总结 四.数组.指针与函数参数 说明:这个C语言专题,是学习iOS开发的前奏.也为了让有面向对象语言开发经验的程序员,能 ...

  9. Emacs as a Python IDE(转)

    赋闲脱产的半年里,自己用C++/Java/Lisp胡乱写了几万行的代码,到了现在的公司,给OpenStack项目贴牛皮藓,反倒是Python用得最多.作为公司里面唯一的Emacser(没准也是 公司里 ...

  10. RequireJs学习笔记之data-main Entry Point

    You will typically use a data-main script to set configuration options and then load the first appli ...