06_javassist
【简述】
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的更多相关文章
随机推荐
- Linux Python import jenkins 报错 oserror: /usr/lib/python2.7/site-packages/lookup3.so
安装了jenkins和Python-jenkins后,在脚本中import jenkins会报错:oserror: /usr/lib/python2.7/site-packages/lookup3.s ...
- list排序问题
用Collections.sort方法对list排序有两种方法第一种是list中的对象实现Comparable接口,如下: /*** 根据order对User排序*/public class User ...
- 基础篇:6.9)GD&T较线性尺寸公差的优缺点
本章目的:理解GD&T标注对比线性/传统/坐标尺寸公差的优势,但也不要忘记其使用限制. 1.线性尺寸公差 1.1 定义 线性尺寸公差=传统尺寸公差=坐标尺寸公差. 传统尺寸公差(Tradi ...
- Vue项目中用的Jquery.js和easing.js做的抛物线
如果项目中还用到自有的$ <script> jQuery.noConflict();</script> //星星掉落movePathNew(args) { let self = ...
- [转] Jenkins pipeline 踩坑集合
[From] https://testerhome.com/topics/10328 前言 最近由于项目需要,接触到了Jenkins 2.0版本,其中最重要的特性就是提供了对pipeline的支持.简 ...
- diff与patch
1.diff diff就是用来比较两个文件之间的区别的,并且是以行为单位比较的,通常用在同一文件或软件的新旧版本区别上. 用法: diff [-bBi] from-file to-file from- ...
- JobScheduler布置后台任务以及实现进程保活?
1.简介 在Android 5.0 提供了一套新的 JobScheduler API,它允许您定义要在以后的某个时间或在指定的条件下(例如,当设备在充电时)异步运行的作业来优化电池寿命. https: ...
- WinForm的Chart图形控件
/// <summary>画条形图的方法 /// </summary> /// <param name="arr">条形值数组参数</pa ...
- C++标准库类模板(stack)和 队列(queue)
在C++标准库(STL)中有栈和队列的类模板,因此可以直接使用 1.栈(stack):使用栈之前,要先包含头文件 : #include<stack> stack.push(elem); / ...
- zookeeper 数据节点的增删改查
1.连接服务端 [root@localhost bin]# ./zkCli.sh -server 127.0.0.1:2181 Connecting to 127.0.0.1:2181 2018-05 ...