Javassist优势

– 比反射开销小,性能高。
–javassist性能高于反射,低于ASM
运行时操作字节码可以让我们实现如下功能:
– 动态生成 新的类
– 动态改变某个类的结构 ( 添加 / 删除 / 修改 新的属性 / 方法 )
javassist 的最外层的 API 和 JAVA 的反射包中的 API 颇为 类似 。
它 主要 由 CtClass , CtMethod, ,以及 CtField 几个类组成。用以执行和 JDK 反射 API 中 java.lang.Class, java.lang.reflect.Method, java.lang.reflect.Method .Field 相同的 操作 。
方法操作
– 修改已有方法的方法体(插入代码到已有方法体)
– 新增方法 删除方法

javassist的局限性
JDK5.0 新语法不支持 ( 包括泛型、枚举 ) ,不支持注解修改,但可以通过底层的 javassist 类来解决,具体参考: javassist.bytecode.annotation
不支持数组的初始化,如 String[]{"1","2"} ,除非只有数组的容量为 1
不支持内部类和匿名类
不支持 continue 和 break表达式。
对于继承关系,有些不支持。例如
class A {}  
class B extends A {} 
class C extends B {}

创建类:

import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtConstructor;
import javassist.CtField;
import javassist.CtMethod;
import javassist.CtNewConstructor; public class App { public static void main(String[] args) throws Exception {
// 利用javassist 创建类 ClassPool poll = ClassPool.getDefault();
// 创建类名 全路径
CtClass ctClass = poll.makeClass("com.hella.thread.jvm.javassist.User");
// 创建属性
CtField name = CtField.make("private String name;", ctClass);
CtField age = CtField.make("private String age;", ctClass); // 属性添加到类中
ctClass.addField(name);
ctClass.addField(age); // 创建get set 方法
CtMethod getName = CtMethod.make("public void getName(){return name;}", ctClass);
CtMethod setName = CtMethod.make("public void setName(String name) {this.name = name;}", ctClass);
CtMethod getAge = CtMethod.make("public String getAge() {return age;}", ctClass);
CtMethod setAge = CtMethod.make("public void setAge(String age) {this.age = age;}", ctClass); // 方法添加到类中
ctClass.addMethod(getName);
ctClass.addMethod(setName);
ctClass.addMethod(getAge);
ctClass.addMethod(setAge); // 创建构造方法
CtConstructor constructor = CtNewConstructor
.make("public User(String name, String age) { this.name = name;this.age = age;}", ctClass); ctClass.addConstructor(constructor); // 生成的位置
ctClass.writeFile("C:/Users/caich5/Desktop/test");
} }

修改类的信息

public class User {

    private String name;

    private String age;

    // 通过字节码技术,在这个类添加以下的方法

    // public int calcute(int a,int b){
// return a + b;
// } }

修改并且执行:

import java.lang.reflect.Method;

import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod; public class Test {
public static void main(String[] args) throws Exception { ClassPool poll = ClassPool.getDefault();
// 获取到class
CtClass ctClass = poll.get("com.hella.thread.jvm.javassist.User");
CtMethod ctMethod = CtMethod.make("public int calcute(int a,int b){ return a + b ;}", ctClass);
ctClass.addMethod(ctMethod);
ctClass.writeFile("C:/Users/caich5/Desktop/test"); // 使用反射执行
Class<?> clazz = ctClass.toClass();
Object newInstance = clazz.newInstance();
Method method = clazz.getDeclaredMethod("calcute", int.class, int.class);
Object res = method.invoke(newInstance, 1, 2);
System.out.println(res); // 需要添加的方法 也可以这样写
// CtMethod m = new CtMethod(CtClass.intType, "add", new CtClass[] {
// CtClass.intType, CtClass.intType },
// userClass);
// // 方法权限
// m.setModifiers(Modifier.PUBLIC);
// // 方法体内容
// m.setBody("{System.out.println(\"Test003\"); return $1+$2;}");
} }

最新文章

  1. canvas arcTo()用法详解
  2. centos7 打开mysql 3306端口并 设置外部访问
  3. 基于CkEditor实现.net在线开发之路(3)常用From表单控件介绍与说明
  4. 代码阅读工具:Source Navigator和Source Insight
  5. centos6.7 mutlipath install script
  6. Nginx问题定位之监控进程异常退出
  7. AC日记—— codevs 1031 质数环(搜索)
  8. input绑定datapicker控件后input再绑定blur或者mouseout等问题
  9. H桥电路
  10. 结对开发--课堂练习--c++
  11. 函数buf_LRU_get_free_only
  12. elecworks 电缆型号管理器
  13. 在JSP页面中调用另一个JSP页面中的变量
  14. [OpenNebula]中间件訪问驱动程序
  15. centos 6.5下安装文件上传下载服务
  16. Qt 如何使用 QImage 设置指定的颜色为透明色?
  17. Java进阶(二)文件读操作
  18. 详解 JSONP跨域请求的实现
  19. 洛谷 P1691 有重复元素的排列问题 解题报告
  20. 还是Go 为了伟大的未来

热门文章

  1. java ThreadPoolExecutor初探
  2. SpringCloud Ribbon组成和负载均衡规则
  3. java集合-set
  4. Java工作流引擎结合可视化表单开发,10分钟完成一个业务流程发布
  5. NLP(二十二)利用ALBERT实现文本二分类
  6. PHP5.6.23+Apache2.4.20+Eclipse for PHP 4.5开发环境配置
  7. Python学习字典.基础三
  8. scrapy中间件中使用selenium切换ip
  9. 关于beforeRouteEnter中的next()
  10. Java并发编程学习前期知识下篇