字节码类库之Javassist
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;}");
} }
字节码类库之Javassist的更多相关文章
- 8.5(java学习笔记)8.5 字节码操作(javassist)
一.javassist javassist让我们操作字节码更加简单,它是一个类库,允许我们修改字节码.它允许java程序动态的创建.修改类. javassist提供了两个层次的API,基于源码级别的和 ...
- 字节码编程,Javassist篇三《使用Javassist在运行时重新加载类「替换原方法输出不一样的结果」》
作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 通过前面两篇 javassist 的基本内容,大体介绍了:类池(ClassPool) ...
- 字节码编程,Javassist篇二《定义属性以及创建方法时多种入参和出参类型的使用》
作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 在上一篇 Helloworld 中,我们初步尝试使用了 Javassist字节编程的 ...
- 字节码编程,Javassist篇一《基于javassist的第一个案例helloworld》
作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 目录 @ 目录 目录 一.前言 二.开发环境 三.案例目标 四.技术实现 五.测试结果 1. ...
- 字节码操作、javassist使用
一.功能 1.动态生成新的类 2.动态改变某个类的结构(添加.删除.修改 新的属性.方法) 二.优势 1.比反射开销小,性能高 2.JAVAasist性能高于反射,低于ASM 使用javassis ...
- JAVA 字节码操作利器javassist
引用:http://blog.csdn.net/hudashi/article/details/50884742 http://blog.csdn.net/haitaofeiyang/article/ ...
- JVM插庄之一:JVM字节码增强技术介绍及入门示例
字节码增强技术:AOP技术其实就是字节码增强技术,JVM提供的动态代理追根究底也是字节码增强技术. 目的:在Java字节码生成之后,对其进行修改,增强其功能,这种方式相当于对应用程序的二进制文件进行修 ...
- JVM(6) 字节码执行引擎
编译器(javac)将Java源文件(.java文件)编译成Java字节码(.class文件). 类加载器负责加载编译后的字节码,并加载到运行时数据区(Runtime Data Area) 通过类加载 ...
- [19/04/20-星期六] Java的动态性_字节码操作(Javassist类库(jar包),assist:帮助、援助)
一.概念 [基本] /** * */ package cn.sxt.jvm; import javassist.ClassPool; import javassist.CtClass; import ...
随机推荐
- 使用D3.js构建实时图形
首先你需要在计算机上安装Node和npm. 数据的可视化表示是传递复杂信息的最有效手段之一,D3.js提供了创建这些数据可视化的强大工具和灵活性. D3.js是一个JavaScript库,用于使用SV ...
- Python-Pyquery库的安装和调用
解析库pyquery:# pip安装pyquery库pip3 install pyquery from pyquery import PyQuery as pq # 定义doc,输入html源代码 d ...
- 负载均衡框架 ribbon 二
Ribbon 负载均衡机制 官方文档地址:https://github.com/Netflix/ribbon/wiki/Working-with-load-balancers 1. Ribbon 内置 ...
- 简单的编写java的helloWord
那么在上一章章节 http://www.cnblogs.com/langjunnan/p/6814641.html 我们简单的俩了解了一下什么是java和配置编写java的环境,本章呢我们学习如何编写 ...
- Html5 部分帮助文档 未完待续
W3cSchoolH5帮助文档 Video属性 视频播放效果 Video标签 src视频得目录 controls属性提供添加 播放 和音量控件 当然呢 不设置宽和高得话 视频会很大 Video还可以 ...
- 为什么你学习了scrum之后还不会实施敏捷? (敏捷学习之旅一)
标题党, 其实这个主题改为"如何能快速的学习与实施敏捷"更贴切. 我在一家大型的外资金融企业,公司最近在大面积的实施敏捷转型,我的团队首先被选为试点团队,并实施得很好,最近我也和不 ...
- ClassLoader&双亲委派&类初始化过程
1.class sycle 类加载的生命周期:加载(Loading)–>验证(Verification)–>准备(Preparation)–>解析(Resolution)–>初 ...
- Effective Go笔记
一 格式化 使用gofmt程序对go源码进行格式化,以便统一编码风格,可直接在GoLand进行配置[1].Go源码格式使用tab作为缩进,且很少使用括号. 二 注释 Go支持块注释/**/和行注释// ...
- 记录一个引用文件所有js文件的方法
在项目api声明的时候,避免每次添加新的js都要对应去处理 首先我在项目api文件下新建一个files的文件夹,然后再api文件夹下的index.js这样写: var api = {}; const ...
- 快速上手项目远程团队协作--CODING(新手向)
快速上手项目远程团队协作--CODING(新手向) CODING网址:https://e.coding.net/signin 前言:之前用过github,用过微软的Azure协作(https://az ...