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的更多相关文章
随机推荐
- PowerBuilder中新建PBL
首先需要打开工作区间workspace , 然后选择你的第一个根pbl文件. 如图所示: 选择WorkSpace下的第一个application.PBT文件,然后单击鼠标右键,选择属性Properti ...
- ORACLE的WITH语句的一个疑惑
使用WITH语句,更新表数据,不行: WITH VN AS ( SELECT T.ID, T.NODE_ID, N.NODE_TYPE, N.NODE_NAME, T.NODE_LEVEL, T.RN ...
- python全栈开发_day10_函数的实参和形参
一:函数的实参和形参 实参是在调用函数时()出现的外界的实际的值 形参不能再函数外部直接使用 1)实参的两种形式 实参是调用函数时()中传入的参数 1.位置实参 def a(a): print(a) ...
- SQL数据库Truncate的相关用法
数据库中 Truncate的用法:这个是删除表中的所有数据语法是 Truncate Table tablename他与delete的区别在于1 delete 可以有条件的删除 而truncate 是删 ...
- chromedriver for mac
- js中自执行函数写法
//自执行写法1 (function T(){ alert(1) })() //自执行写法2 var T1=function(){ alert(1) }(); //传值 var para1={a:1; ...
- jstack Dump 日志文件中的线程状态(转)
jstack Dump 日志文件中的线程状态 dump 文件里,值得关注的线程状态有: 死锁,Deadlock(重点关注) 执行中,Runnable 等待资源,Waiting on conditio ...
- c#异步编程async await
可以代替协程了 但是需要.net4 版本 unity2017以上版本可以用了 再也可以不用蛋疼的没有返回值的协程了 //异步编程,和Task一起用 async void TestAsync(){ // ...
- hadoop源码svn下载地址
1.apache开源框架
- Ubuntu 下常用的命令 简略记录
# 动态显示 NVIDIA watch -n 1 nvidia-smi #查看某一目录下文件的总数(不包含子目录) ls -l | wc -l #挂载硬盘或者U盘 mount /dev/sdb1 /m ...