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的更多相关文章

  1. 8.5(java学习笔记)8.5 字节码操作(javassist)

    一.javassist javassist让我们操作字节码更加简单,它是一个类库,允许我们修改字节码.它允许java程序动态的创建.修改类. javassist提供了两个层次的API,基于源码级别的和 ...

  2. 字节码编程,Javassist篇三《使用Javassist在运行时重新加载类「替换原方法输出不一样的结果」》

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 通过前面两篇 javassist 的基本内容,大体介绍了:类池(ClassPool) ...

  3. 字节码编程,Javassist篇二《定义属性以及创建方法时多种入参和出参类型的使用》

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 在上一篇 Helloworld 中,我们初步尝试使用了 Javassist字节编程的 ...

  4. 字节码编程,Javassist篇一《基于javassist的第一个案例helloworld》

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 目录 @ 目录 目录 一.前言 二.开发环境 三.案例目标 四.技术实现 五.测试结果 1. ...

  5. 字节码操作、javassist使用

    一.功能 1.动态生成新的类 2.动态改变某个类的结构(添加.删除.修改   新的属性.方法) 二.优势 1.比反射开销小,性能高 2.JAVAasist性能高于反射,低于ASM 使用javassis ...

  6. JAVA 字节码操作利器javassist

    引用:http://blog.csdn.net/hudashi/article/details/50884742 http://blog.csdn.net/haitaofeiyang/article/ ...

  7. JVM插庄之一:JVM字节码增强技术介绍及入门示例

    字节码增强技术:AOP技术其实就是字节码增强技术,JVM提供的动态代理追根究底也是字节码增强技术. 目的:在Java字节码生成之后,对其进行修改,增强其功能,这种方式相当于对应用程序的二进制文件进行修 ...

  8. JVM(6) 字节码执行引擎

    编译器(javac)将Java源文件(.java文件)编译成Java字节码(.class文件). 类加载器负责加载编译后的字节码,并加载到运行时数据区(Runtime Data Area) 通过类加载 ...

  9. [19/04/20-星期六] Java的动态性_字节码操作(Javassist类库(jar包),assist:帮助、援助)

    一.概念 [基本] /** * */ package cn.sxt.jvm; import javassist.ClassPool; import javassist.CtClass; import ...

随机推荐

  1. 分割文件和数据(linux)

    在某些情况下,必须把文件分割成多个更小的片段.如今我们分割文件的目的比如:提高可读性.生成日志.通过Email发送文件等等. 假设我们有一个erro.log的测试文件,其大小为14M.你可以将该文件分 ...

  2. SQL基本操作总结

    1.SQL简介 结构化查询语言 (层次模型,网状模型,关系模型) 关系模型是目前的主流 (Oralce,mysql mssql ) SQL标准:ANSI (1992 1997 2002 ISO) 方言 ...

  3. 学习经典算法—JavaScript篇(一)排序算法

    前端攻城狮--学习常用的排序算法 一.冒泡排序 优点: 所有排序中最简单的,易于理解: 缺点: 时间复杂度O(n^2),平均来说是最差的一种排序方式: 因为在默认情况下,对于已经排好序的部分,此排序任 ...

  4. Dubbo 入门-细说分布式与集群

    什么是Dubbo Dubbo是一款高性能.轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现. 什么是RPC RPC全称(Rem ...

  5. docker 学习路线

    docker 学习路线 参考资料 知乎 docker 的学习路线 Docker - 从入门到实践 Docker 核心技术与实现原理 Docker 入门 <Kubernetes in Action ...

  6. Go语言:如何解决读取不到相对路径配置文件问题

    背景 项目交叉编译为可执行文件之后,在其他目录执行文件时提示找不到配置文件 2020/03/14 20:44:23 配置文件读取失败 open config.ini: no such file or ...

  7. MySQL 整体架构一览

    MySQL 在整体架构上分为 Server 层和存储引擎层.其中 Server 层,包括连接器.查询缓存.分析器.优化器.执行器等,存储过程.触发器.视图和内置函数都在这层实现.数据引擎层负责数据的存 ...

  8. Docker深入浅出系列 | 5分钟搭建你的私有镜像仓库

    Docker已经上市很多年,不是什么新鲜事物了,很多企业或者开发同学以前也不多不少有所接触,但是有实操经验的人不多,本系列教程主要偏重实战,尽量讲干货,会根据本人理解去做阐述,具体官方概念可以查阅官方 ...

  9. Ubuntu下搭建.Net Core环境并发布MVC项目

    支撑环境 1. Windows 10 1809 12月更新版本(其他版本应该也行,但建议不低于1809,过低的版本可能无法安装子系统ubuntu18.04 LTS) 2. ubuntu 18.04 L ...

  10. 【MyBatis笔记】mapper文件的配置以及说明

    <!doctype html>[MyBatis笔记]mapper文件的配置以及说明 figure:last-child { margin-bottom: 0.5rem; } #write ...