下面就是一个具体的demo来介绍利用Javaassist库来创建类,不过要先在工程里面导入Javaassist的架包,

  1. package JavaAasist;
  2.  
  3. import java.lang.reflect.Method;
  4. import java.util.Arrays;
  5.  
  6. import javassist.ClassPool;
  7. import javassist.CtClass;
  8. import javassist.CtConstructor;
  9. import javassist.CtField;
  10. import javassist.CtMethod;
  11. import javassist.CtNewMethod;
  12. import javassist.Modifier;
  13.  
  14. /**
  15. * 测试javassist的API
  16. * @author 尚学堂高淇 www.sxt.cn
  17. *
  18. */
  19. public class DEmo02 {
  20. /**
  21. * 处理类的基本用法
  22. * @throws Exception
  23. */
  24. public static void test01() throws Exception{
  25. ClassPool pool = ClassPool.getDefault();
  26. CtClass cc = pool.get("com.bjsxt.test.Emp");
  27.  
  28. byte[] bytes = cc.toBytecode();
  29. System.out.println(Arrays.toString(bytes));
  30.  
  31. System.out.println(cc.getName()); //获取类名
  32. System.out.println(cc.getSimpleName()); //获取简要类名
  33. System.out.println(cc.getSuperclass()); //获得父类
  34. System.out.println(cc.getInterfaces()); //获得接口
  35.  
  36. }
  37.  
  38. /**
  39. * 测试产生新的方法
  40. * @throws Exception
  41. */
  42. public static void test02() throws Exception{
  43. ClassPool pool = ClassPool.getDefault();
  44. CtClass cc = pool.get("com.bjsxt.test.Emp");
  45.  
  46. // CtMethod m = CtNewMethod.make("public int add(int a,int b){return a+b;}", cc);
  47.  
  48. CtMethod m = new CtMethod(CtClass.intType,"add",
  49. new CtClass[]{CtClass.intType,CtClass.intType},cc);
  50. m.setModifiers(Modifier.PUBLIC);
  51. m.setBody("{System.out.println(\"www.sxt.cn\");return $1+$2;}");
  52.  
  53. cc.addMethod(m);
  54.  
  55. //通过反射调用新生成的方法
  56. Class clazz = cc.toClass();
  57. Object obj = clazz.newInstance(); //通过调用Emp无参构造器,创建新的Emp对象
  58. Method method = clazz.getDeclaredMethod("add", int.class,int.class);
  59. Object result = method.invoke(obj, ,);
  60. System.out.println(result);
  61. }
  62.  
  63. /**
  64. * 修改已有的方法的信息,修改方法体的内容
  65. * @throws Exception
  66. */
  67. public static void test03() throws Exception{
  68. ClassPool pool = ClassPool.getDefault();
  69. CtClass cc = pool.get("com.bjsxt.test.Emp");
  70.  
  71. CtMethod cm = cc.getDeclaredMethod("sayHello",new CtClass[]{CtClass.intType});
  72. cm.insertBefore("System.out.println($1);System.out.println(\"start!!!\");");
  73. cm.insertAt(, "int b=3;System.out.println(\"b=\"+b);");
  74. cm.insertAfter("System.out.println(\"end!!!\");");
  75.  
  76. //通过反射调用新生成的方法
  77. Class clazz = cc.toClass();
  78. Object obj = clazz.newInstance(); //通过调用Emp无参构造器,创建新的Emp对象
  79. Method method = clazz.getDeclaredMethod("sayHello", int.class);
  80. method.invoke(obj, );
  81. }
  82.  
  83. /**
  84. * 属性的操作
  85. * @throws Exception
  86. */
  87. public static void test04() throws Exception{
  88. ClassPool pool = ClassPool.getDefault();
  89. CtClass cc = pool.get("com.bjsxt.test.Emp");
  90.  
  91. // CtField f1 = CtField.make("private int empno;", cc);
  92. CtField f1 = new CtField(CtClass.intType,"salary",cc);
  93. f1.setModifiers(Modifier.PRIVATE);
  94. cc.addField(f1);
  95.  
  96. // cc.getDeclaredField("ename"); //获取指定的属性
  97.  
  98. //增加相应的set和get方法
  99. cc.addMethod(CtNewMethod.getter("getSalary", f1));;
  100. cc.addMethod(CtNewMethod.getter("setSalary", f1));;
  101.  
  102. }
  103.  
  104. /**
  105. * 构造方法的操作
  106. * @throws Exception
  107. */
  108. public static void test05() throws Exception {
  109. ClassPool pool = ClassPool.getDefault();
  110. CtClass cc = pool.get("com.bjsxt.test.Emp");
  111.  
  112. CtConstructor[] cs = cc.getConstructors();
  113. for (CtConstructor c : cs) {
  114. System.out.println(c.getLongName());
  115. }
  116. }
  117.  
  118. public static void test06() throws Exception{
  119. CtClass cc = ClassPool.getDefault().get("com.bjsxt.test.Emp");
  120. Object[] all = cc.getAnnotations();
  121. Author a = (Author)all[];
  122. String name = a.name();
  123. int year = a.year();
  124. System.out.println("name: " + name + ", year: " + year);
  125.  
  126. }
  127.  
  128. public static void main(String[] args) throws Exception {
  129. test06();
  130. }
  131. }

运行改代码则在对应路径生成一个java文件,不过该文件需要反编译才可以查看,具体的工具是xjad

下面是JavaAssist处理类的demo

  1. package JavaAssist;
  2.  
  3. import java.lang.reflect.Method;
  4. import java.util.Arrays;
  5.  
  6. import javassist.ClassPool;
  7. import javassist.CtClass;
  8. import javassist.CtConstructor;
  9. import javassist.CtField;
  10. import javassist.CtMethod;
  11. import javassist.CtNewMethod;
  12. import javassist.Modifier;
  13.  
  14. /**
  15. * 测试javassist的API
  16. * @author 19579
  17. *
  18. */
  19. public class DEmo02 {
  20. /**
  21. * 处理类的基本用法
  22. * @throws Exception
  23. */
  24. public static void test01() throws Exception{
  25. ClassPool pool = ClassPool.getDefault();
  26. CtClass cc = pool.get("JavaAssist.Emp");
  27.  
  28. byte[] bytes = cc.toBytecode();
  29. System.out.println(Arrays.toString(bytes));
  30.  
  31. System.out.println(cc.getName()); //获取类名
  32. System.out.println(cc.getSimpleName()); //获取简要类名
  33. System.out.println(cc.getSuperclass()); //获得父类
  34. System.out.println(cc.getInterfaces()); //获得接口
  35.  
  36. }
  37.  
  38. /**
  39. * 测试产生新的方法
  40. * @throws Exception
  41. */
  42. public static void test02() throws Exception{
  43. ClassPool pool = ClassPool.getDefault();
  44. CtClass cc = pool.get("JavaAssist.Emp");
  45.  
  46. // CtMethod m = CtNewMethod.make("public int add(int a,int b){return a+b;}", cc);
  47.  
  48. CtMethod m = new CtMethod(CtClass.intType,"add",
  49. new CtClass[]{CtClass.intType,CtClass.intType},cc);
  50. m.setModifiers(Modifier.PUBLIC);
  51. m.setBody("{System.out.println(\"www.sxt.cn\");return $1+$2;}");//$1和$2分别指两个形参
  52.  
  53. cc.addMethod(m);
  54.  
  55. //通过反射调用新生成的方法
  56. Class clazz = cc.toClass();
  57. Object obj = clazz.newInstance(); //通过调用Emp无参构造器,创建新的Emp对象
  58. Method method = clazz.getDeclaredMethod("add", int.class,int.class);
  59. Object result = method.invoke(obj, ,);
  60. System.out.println(result);
  61. }
  62.  
  63. /**
  64. * 修改已有的方法的信息,修改方法体的内容
  65. * @throws Exception
  66. */
  67. public static void test03() throws Exception{
  68. ClassPool pool = ClassPool.getDefault();
  69. CtClass cc = pool.get("JavaAssist.Emp");
  70.  
  71. CtMethod cm = cc.getDeclaredMethod("sayHello",new CtClass[]{CtClass.intType});
  72. cm.insertBefore("System.out.println($1);System.out.println(\"start!!!\");");//在方法体前加入
  73. cm.insertAt(, "int b=3;System.out.println(\"b=\"+b);");//具体的第9行加入
  74. cm.insertAfter("System.out.println(\"end!!!\");");//在方法后面加入
  75.  
  76. //通过反射调用新生成的方法
  77. Class clazz = cc.toClass();
  78. Object obj = clazz.newInstance(); //通过调用Emp无参构造器,创建新的Emp对象
  79. Method method = clazz.getDeclaredMethod("sayHello", int.class);
  80. method.invoke(obj, );
  81. }
  82.  
  83. /**
  84. * 属性的操作
  85. * @throws Exception
  86. */
  87. public static void test04() throws Exception{
  88. ClassPool pool = ClassPool.getDefault();
  89. CtClass cc = pool.get("JavaAssist.Emp");
  90.  
  91. // CtField f1 = CtField.make("private int empno;", cc);
  92. CtField f1 = new CtField(CtClass.intType,"salary",cc);
  93. f1.setModifiers(Modifier.PRIVATE);
  94. cc.addField(f1);
  95.  
  96. // cc.getDeclaredField("ename"); //获取指定的属性
  97.  
  98. //增加相应的set和get方法
  99. cc.addMethod(CtNewMethod.getter("getSalary", f1));;
  100. cc.addMethod(CtNewMethod.getter("setSalary", f1));;
  101.  
  102. }
  103.  
  104. /**
  105. * 构造方法的操作
  106. * @throws Exception
  107. */
  108. public static void test05() throws Exception {
  109. ClassPool pool = ClassPool.getDefault();
  110. CtClass cc = pool.get("JavaAssist.Emp");
  111.  
  112. CtConstructor[] cs = cc.getConstructors();
  113. for (CtConstructor c : cs) {
  114. System.out.println(c.getLongName());
  115. }
  116. }
  117.  
  118. public static void test06() throws Exception{
  119. CtClass cc = ClassPool.getDefault().get("JavaAssist.Emp");
  120. Object[] all = cc.getAnnotations();
  121. Author a = (Author)all[];
  122. String name = a.name();
  123. int year = a.year();
  124. System.out.println("name: " + name + ", year: " + year);
  125.  
  126. }
  127.  
  128. public static void main(String[] args) throws Exception {
  129. test06();
  130. }
  131. }

对应的emp类如下

  1. package com.bjsxt.test;
  2.  
  3. @Author(name="gaoqi", year=)
  4. public class Emp {
  5.  
  6. private int empno;
  7. private String ename;
  8.  
  9. public void sayHello(int a){
  10. System.out.println("sayHello,"+a);
  11. }
  12.  
  13. public int getEmpno() {
  14. return empno;
  15. }
  16. public void setEmpno(int empno) {
  17. this.empno = empno;
  18. }
  19. public String getEname() {
  20. return ename;
  21. }
  22. public void setEname(String ename) {
  23. this.ename = ename;
  24. }
  25.  
  26. public Emp(int empno, String ename) {
  27. super();
  28. this.empno = empno;
  29. this.ename = ename;
  30. }
  31.  
  32. public Emp() {
  33. }
  34. }
  35.  
  36. Author类如下
  37.  
  38. package com.bjsxt.test;
  39. public @interface Author {
  40. String name();
  41. int year();
  42. }

当然javaAssist也有自己的局限性

字节码操作-Javaassist的更多相关文章

  1. 尚学堂 216 java中的字节码操作

    所谓的字节码操作就是操作我们已经加载的字节码 接下来我们重点来讲解javaassist类库 使用需要下载jar包,把jar包添加到对应的工程之后 package com.bjsxt.test; pub ...

  2. 字节码操作JAVAssist

    字节码操作Javassist 字节码:字节码是设计被用来将代码高效的传送给多种软件平台.硬件平台,字节码的设计也实现了Java的平台无关性,字节码比机器码更抽象,它通常被认为是包含了一个可执行文件的二 ...

  3. JAVAssist字节码操作

    Java动态性的两种常见实现方式 字节码操作 反射 运行时操作字节码可以让我们实现如下功能: 动态生成新的类 动态改变某个类的结构(添加/删除/修改  新的属性/方法) 优势: 比反射开销小,性能高 ...

  4. Java动态性 字节码操作

    Java动态性的两种常见方式:-字节码操作 - 反射;字节码操作比反射开销小,性能高,JAVAasist性能高于反射,低于ASM 运行时操作字节码可是实现  : 动态生成新的类:动态的改变某个类的结构 ...

  5. Javassist 字节码操作

    1.读写字节码 Javassist是用来处理java字节码的类库.字节码保存在二进制文件中称为类文件.每个类文件夹包括一个java类或接口. Javasssist.CtClass这个类是一个类文件的抽 ...

  6. 关于360插件化Replugin Activity动态修改父类的字节码操作

    近期在接入360插件化方案Replugin时,发现出现崩溃情况. 大概崩溃内容如下: aused by: java.lang.ClassNotFoundException: Didn't find c ...

  7. Java的动态编译、动态加载、字节码操作

    想起来之前做的一个项目:那时候是把需要的源代码通过文件流输出到一个.java文件里,然后调用sun的Comipler接口动态编译成.class文件,然后再用专门写的一个class loader加载这个 ...

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

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

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

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

随机推荐

  1. JS性能优化——数据存取

    首先,了解几个概念: 字面量:它只代表自身,不存储在特定的位置.JavaScript中的字面量有:字符串.数字.布尔值.对象.数组.函数.正则,以及特殊的null和undefined值 本地变量:使用 ...

  2. MySQL——sql语句的执行顺序

    #核心知识点: 书写顺序:where——>group by——>having——>order by——>limit 许多时候在书写一些复杂的sql语句的时候,尤其是在渐进式推导 ...

  3. java.sql.SQLException: Illegal connection port value '3306:success'

    严重: Servlet.service() for servlet jsp threw exceptionjava.sql.SQLException: Illegal connection port ...

  4. hadoop —— eclipse插件安装配置

    安装: 1. 将hadoop-core-0.20.2-cdh3u6/contrib/eclipse-plugin/hadoop-eclipse-plugin-0.20.2-cdh3u6.jar拷贝到e ...

  5. HDU 4336 Card Collector:状压 + 期望dp

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4336 题意: 有n种卡片(n <= 20). 对于每一包方便面,里面有卡片i的概率为p[i],可 ...

  6. listen 64

    Winning Athletes Engage in Arms Raise You see it when you watch almost any game: there's a touchdown ...

  7. linux 进程学习笔记-named pipe (FIFO)命名管道

    与“无名管道”不同的是,FIFO拥有一个名称来标志它,所谓的名称实际上就是一个路径,比如“/tmp/my_fifo”,其对应到磁盘上的一个管道文件,如果我们用file命令来查看其文件类型的话,会得到如 ...

  8. Qt容器组件(二)之QWidgetStack、QMdiArea、QDockWidget

    QT中有九种容器组件,分别是组合框QGroupBox.滚动区QScrollArea.工具箱QToolBox.选项卡QTabWidget.控件栈QWidgetStack.框架QFrame.组件QWidg ...

  9. html制作细线表格

    关于这个细线表格的制作方法,百度一下可能就会有答案告诉你设置这几个值:给table设置border="0" cellspacing="1" bgcolor=&q ...

  10. poj1966Cable TV Network——无向图最小割(最大流)

    题目:http://poj.org/problem?id=1966 把一个点拆成入点和出点,之间连一条边权为1的边,跑最大流即最小割: 原始的边权赋成inf防割: 枚举源点和汇点,直接相邻的两个点不必 ...