字节码操作-Javaassist
下面就是一个具体的demo来介绍利用Javaassist库来创建类,不过要先在工程里面导入Javaassist的架包,
- package JavaAasist;
- import java.lang.reflect.Method;
- import java.util.Arrays;
- import javassist.ClassPool;
- import javassist.CtClass;
- import javassist.CtConstructor;
- import javassist.CtField;
- import javassist.CtMethod;
- import javassist.CtNewMethod;
- import javassist.Modifier;
- /**
- * 测试javassist的API
- * @author 尚学堂高淇 www.sxt.cn
- *
- */
- public class DEmo02 {
- /**
- * 处理类的基本用法
- * @throws Exception
- */
- public static void test01() throws Exception{
- ClassPool pool = ClassPool.getDefault();
- CtClass cc = pool.get("com.bjsxt.test.Emp");
- byte[] bytes = cc.toBytecode();
- System.out.println(Arrays.toString(bytes));
- System.out.println(cc.getName()); //获取类名
- System.out.println(cc.getSimpleName()); //获取简要类名
- System.out.println(cc.getSuperclass()); //获得父类
- System.out.println(cc.getInterfaces()); //获得接口
- }
- /**
- * 测试产生新的方法
- * @throws Exception
- */
- public static void test02() throws Exception{
- ClassPool pool = ClassPool.getDefault();
- CtClass cc = pool.get("com.bjsxt.test.Emp");
- // CtMethod m = CtNewMethod.make("public int add(int a,int b){return a+b;}", cc);
- CtMethod m = new CtMethod(CtClass.intType,"add",
- new CtClass[]{CtClass.intType,CtClass.intType},cc);
- m.setModifiers(Modifier.PUBLIC);
- m.setBody("{System.out.println(\"www.sxt.cn\");return $1+$2;}");
- cc.addMethod(m);
- //通过反射调用新生成的方法
- Class clazz = cc.toClass();
- Object obj = clazz.newInstance(); //通过调用Emp无参构造器,创建新的Emp对象
- Method method = clazz.getDeclaredMethod("add", int.class,int.class);
- Object result = method.invoke(obj, ,);
- System.out.println(result);
- }
- /**
- * 修改已有的方法的信息,修改方法体的内容
- * @throws Exception
- */
- public static void test03() throws Exception{
- ClassPool pool = ClassPool.getDefault();
- CtClass cc = pool.get("com.bjsxt.test.Emp");
- CtMethod cm = cc.getDeclaredMethod("sayHello",new CtClass[]{CtClass.intType});
- cm.insertBefore("System.out.println($1);System.out.println(\"start!!!\");");
- cm.insertAt(, "int b=3;System.out.println(\"b=\"+b);");
- cm.insertAfter("System.out.println(\"end!!!\");");
- //通过反射调用新生成的方法
- Class clazz = cc.toClass();
- Object obj = clazz.newInstance(); //通过调用Emp无参构造器,创建新的Emp对象
- Method method = clazz.getDeclaredMethod("sayHello", int.class);
- method.invoke(obj, );
- }
- /**
- * 属性的操作
- * @throws Exception
- */
- public static void test04() throws Exception{
- ClassPool pool = ClassPool.getDefault();
- CtClass cc = pool.get("com.bjsxt.test.Emp");
- // CtField f1 = CtField.make("private int empno;", cc);
- CtField f1 = new CtField(CtClass.intType,"salary",cc);
- f1.setModifiers(Modifier.PRIVATE);
- cc.addField(f1);
- // cc.getDeclaredField("ename"); //获取指定的属性
- //增加相应的set和get方法
- cc.addMethod(CtNewMethod.getter("getSalary", f1));;
- cc.addMethod(CtNewMethod.getter("setSalary", f1));;
- }
- /**
- * 构造方法的操作
- * @throws Exception
- */
- public static void test05() throws Exception {
- ClassPool pool = ClassPool.getDefault();
- CtClass cc = pool.get("com.bjsxt.test.Emp");
- CtConstructor[] cs = cc.getConstructors();
- for (CtConstructor c : cs) {
- System.out.println(c.getLongName());
- }
- }
- public static void test06() throws Exception{
- CtClass cc = ClassPool.getDefault().get("com.bjsxt.test.Emp");
- Object[] all = cc.getAnnotations();
- Author a = (Author)all[];
- String name = a.name();
- int year = a.year();
- System.out.println("name: " + name + ", year: " + year);
- }
- public static void main(String[] args) throws Exception {
- test06();
- }
- }
运行改代码则在对应路径生成一个java文件,不过该文件需要反编译才可以查看,具体的工具是xjad
下面是JavaAssist处理类的demo
- package JavaAssist;
- import java.lang.reflect.Method;
- import java.util.Arrays;
- import javassist.ClassPool;
- import javassist.CtClass;
- import javassist.CtConstructor;
- import javassist.CtField;
- import javassist.CtMethod;
- import javassist.CtNewMethod;
- import javassist.Modifier;
- /**
- * 测试javassist的API
- * @author 19579
- *
- */
- public class DEmo02 {
- /**
- * 处理类的基本用法
- * @throws Exception
- */
- public static void test01() throws Exception{
- ClassPool pool = ClassPool.getDefault();
- CtClass cc = pool.get("JavaAssist.Emp");
- byte[] bytes = cc.toBytecode();
- System.out.println(Arrays.toString(bytes));
- System.out.println(cc.getName()); //获取类名
- System.out.println(cc.getSimpleName()); //获取简要类名
- System.out.println(cc.getSuperclass()); //获得父类
- System.out.println(cc.getInterfaces()); //获得接口
- }
- /**
- * 测试产生新的方法
- * @throws Exception
- */
- public static void test02() throws Exception{
- ClassPool pool = ClassPool.getDefault();
- CtClass cc = pool.get("JavaAssist.Emp");
- // CtMethod m = CtNewMethod.make("public int add(int a,int b){return a+b;}", cc);
- CtMethod m = new CtMethod(CtClass.intType,"add",
- new CtClass[]{CtClass.intType,CtClass.intType},cc);
- m.setModifiers(Modifier.PUBLIC);
- m.setBody("{System.out.println(\"www.sxt.cn\");return $1+$2;}");//$1和$2分别指两个形参
- cc.addMethod(m);
- //通过反射调用新生成的方法
- Class clazz = cc.toClass();
- Object obj = clazz.newInstance(); //通过调用Emp无参构造器,创建新的Emp对象
- Method method = clazz.getDeclaredMethod("add", int.class,int.class);
- Object result = method.invoke(obj, ,);
- System.out.println(result);
- }
- /**
- * 修改已有的方法的信息,修改方法体的内容
- * @throws Exception
- */
- public static void test03() throws Exception{
- ClassPool pool = ClassPool.getDefault();
- CtClass cc = pool.get("JavaAssist.Emp");
- CtMethod cm = cc.getDeclaredMethod("sayHello",new CtClass[]{CtClass.intType});
- cm.insertBefore("System.out.println($1);System.out.println(\"start!!!\");");//在方法体前加入
- cm.insertAt(, "int b=3;System.out.println(\"b=\"+b);");//具体的第9行加入
- cm.insertAfter("System.out.println(\"end!!!\");");//在方法后面加入
- //通过反射调用新生成的方法
- Class clazz = cc.toClass();
- Object obj = clazz.newInstance(); //通过调用Emp无参构造器,创建新的Emp对象
- Method method = clazz.getDeclaredMethod("sayHello", int.class);
- method.invoke(obj, );
- }
- /**
- * 属性的操作
- * @throws Exception
- */
- public static void test04() throws Exception{
- ClassPool pool = ClassPool.getDefault();
- CtClass cc = pool.get("JavaAssist.Emp");
- // CtField f1 = CtField.make("private int empno;", cc);
- CtField f1 = new CtField(CtClass.intType,"salary",cc);
- f1.setModifiers(Modifier.PRIVATE);
- cc.addField(f1);
- // cc.getDeclaredField("ename"); //获取指定的属性
- //增加相应的set和get方法
- cc.addMethod(CtNewMethod.getter("getSalary", f1));;
- cc.addMethod(CtNewMethod.getter("setSalary", f1));;
- }
- /**
- * 构造方法的操作
- * @throws Exception
- */
- public static void test05() throws Exception {
- ClassPool pool = ClassPool.getDefault();
- CtClass cc = pool.get("JavaAssist.Emp");
- CtConstructor[] cs = cc.getConstructors();
- for (CtConstructor c : cs) {
- System.out.println(c.getLongName());
- }
- }
- public static void test06() throws Exception{
- CtClass cc = ClassPool.getDefault().get("JavaAssist.Emp");
- Object[] all = cc.getAnnotations();
- Author a = (Author)all[];
- String name = a.name();
- int year = a.year();
- System.out.println("name: " + name + ", year: " + year);
- }
- public static void main(String[] args) throws Exception {
- test06();
- }
- }
对应的emp类如下
- package com.bjsxt.test;
- @Author(name="gaoqi", year=)
- public class Emp {
- private int empno;
- private String ename;
- public void sayHello(int a){
- System.out.println("sayHello,"+a);
- }
- public int getEmpno() {
- return empno;
- }
- public void setEmpno(int empno) {
- this.empno = empno;
- }
- public String getEname() {
- return ename;
- }
- public void setEname(String ename) {
- this.ename = ename;
- }
- public Emp(int empno, String ename) {
- super();
- this.empno = empno;
- this.ename = ename;
- }
- public Emp() {
- }
- }
- Author类如下
- package com.bjsxt.test;
- public @interface Author {
- String name();
- int year();
- }
当然javaAssist也有自己的局限性
字节码操作-Javaassist的更多相关文章
- 尚学堂 216 java中的字节码操作
所谓的字节码操作就是操作我们已经加载的字节码 接下来我们重点来讲解javaassist类库 使用需要下载jar包,把jar包添加到对应的工程之后 package com.bjsxt.test; pub ...
- 字节码操作JAVAssist
字节码操作Javassist 字节码:字节码是设计被用来将代码高效的传送给多种软件平台.硬件平台,字节码的设计也实现了Java的平台无关性,字节码比机器码更抽象,它通常被认为是包含了一个可执行文件的二 ...
- JAVAssist字节码操作
Java动态性的两种常见实现方式 字节码操作 反射 运行时操作字节码可以让我们实现如下功能: 动态生成新的类 动态改变某个类的结构(添加/删除/修改 新的属性/方法) 优势: 比反射开销小,性能高 ...
- Java动态性 字节码操作
Java动态性的两种常见方式:-字节码操作 - 反射;字节码操作比反射开销小,性能高,JAVAasist性能高于反射,低于ASM 运行时操作字节码可是实现 : 动态生成新的类:动态的改变某个类的结构 ...
- Javassist 字节码操作
1.读写字节码 Javassist是用来处理java字节码的类库.字节码保存在二进制文件中称为类文件.每个类文件夹包括一个java类或接口. Javasssist.CtClass这个类是一个类文件的抽 ...
- 关于360插件化Replugin Activity动态修改父类的字节码操作
近期在接入360插件化方案Replugin时,发现出现崩溃情况. 大概崩溃内容如下: aused by: java.lang.ClassNotFoundException: Didn't find c ...
- Java的动态编译、动态加载、字节码操作
想起来之前做的一个项目:那时候是把需要的源代码通过文件流输出到一个.java文件里,然后调用sun的Comipler接口动态编译成.class文件,然后再用专门写的一个class loader加载这个 ...
- [19/04/20-星期六] Java的动态性_字节码操作(Javassist类库(jar包),assist:帮助、援助)
一.概念 [基本] /** * */ package cn.sxt.jvm; import javassist.ClassPool; import javassist.CtClass; import ...
- 8.5(java学习笔记)8.5 字节码操作(javassist)
一.javassist javassist让我们操作字节码更加简单,它是一个类库,允许我们修改字节码.它允许java程序动态的创建.修改类. javassist提供了两个层次的API,基于源码级别的和 ...
随机推荐
- JS性能优化——数据存取
首先,了解几个概念: 字面量:它只代表自身,不存储在特定的位置.JavaScript中的字面量有:字符串.数字.布尔值.对象.数组.函数.正则,以及特殊的null和undefined值 本地变量:使用 ...
- MySQL——sql语句的执行顺序
#核心知识点: 书写顺序:where——>group by——>having——>order by——>limit 许多时候在书写一些复杂的sql语句的时候,尤其是在渐进式推导 ...
- java.sql.SQLException: Illegal connection port value '3306:success'
严重: Servlet.service() for servlet jsp threw exceptionjava.sql.SQLException: Illegal connection port ...
- hadoop —— eclipse插件安装配置
安装: 1. 将hadoop-core-0.20.2-cdh3u6/contrib/eclipse-plugin/hadoop-eclipse-plugin-0.20.2-cdh3u6.jar拷贝到e ...
- HDU 4336 Card Collector:状压 + 期望dp
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4336 题意: 有n种卡片(n <= 20). 对于每一包方便面,里面有卡片i的概率为p[i],可 ...
- listen 64
Winning Athletes Engage in Arms Raise You see it when you watch almost any game: there's a touchdown ...
- linux 进程学习笔记-named pipe (FIFO)命名管道
与“无名管道”不同的是,FIFO拥有一个名称来标志它,所谓的名称实际上就是一个路径,比如“/tmp/my_fifo”,其对应到磁盘上的一个管道文件,如果我们用file命令来查看其文件类型的话,会得到如 ...
- Qt容器组件(二)之QWidgetStack、QMdiArea、QDockWidget
QT中有九种容器组件,分别是组合框QGroupBox.滚动区QScrollArea.工具箱QToolBox.选项卡QTabWidget.控件栈QWidgetStack.框架QFrame.组件QWidg ...
- html制作细线表格
关于这个细线表格的制作方法,百度一下可能就会有答案告诉你设置这几个值:给table设置border="0" cellspacing="1" bgcolor=&q ...
- poj1966Cable TV Network——无向图最小割(最大流)
题目:http://poj.org/problem?id=1966 把一个点拆成入点和出点,之间连一条边权为1的边,跑最大流即最小割: 原始的边权赋成inf防割: 枚举源点和汇点,直接相邻的两个点不必 ...