尚学堂 217 java中的字节码操作2
package com.bjsxt.test; @Author(name="gaoqi", year=2014)
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() {
}
}
我们测试javaAssit的常用api代码
package com.bjsxt.test; 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;
import javassist.NotFoundException; /**
* 测试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); /*
*CtClass.intType,CtClass.intType是add函数的两个形参的类型这里没有制定形参的名字,这里通过占位符来指定形参名字
$0表示this对象
$1表示第一个形参
$2表示第二个形参
*/
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, 200,300);
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(9, "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, 300);
} /**
* 添加新的属性的操作
* @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[0];
String name = a.name();
int year = a.year();
System.out.println("name: " + name + ", year: " + year); } public static void main(String[] args) throws Exception {
test06();
}
}
package com.bjsxt.test;
public @interface Author {
String name();
int year();
}
尚学堂 217 java中的字节码操作2的更多相关文章
- 尚学堂 216 java中的字节码操作
所谓的字节码操作就是操作我们已经加载的字节码 接下来我们重点来讲解javaassist类库 使用需要下载jar包,把jar包添加到对应的工程之后 package com.bjsxt.test; pub ...
- 深圳尚学堂:Java中Class对象
Java中生成Class对象和生成instance都有多种方式.所以只有弄清其中的原理,才可以深入理解.首先要生成Class对象,然后再生成Instance.那Class对象的生成方式有哪些呢,以及其 ...
- 深圳尚学堂:JavaScript中常见的字符串操作
快到春节放假了,春节后又是一大波的找工作热潮,在前端实招聘笔试时,必不可免额会考到关于JavaScript中字符串的处理问题.考的不是你会不会,而是你能不能在不借用XX手册或者XX指南再或者百度谷歌的 ...
- 字节码操作JAVAssist
字节码操作Javassist 字节码:字节码是设计被用来将代码高效的传送给多种软件平台.硬件平台,字节码的设计也实现了Java的平台无关性,字节码比机器码更抽象,它通常被认为是包含了一个可执行文件的二 ...
- 深入浅出Java探针技术1--基于java agent的字节码增强案例
Java agent又叫做Java 探针,本文将从以下四个问题出发来深入浅出了解下Java agent 一.什么是java agent? Java agent是在JDK1.5引入的,是一种可以动态修改 ...
- Java虚拟机--虚拟机字节码执行引擎
Java虚拟机--虚拟机字节码执行引擎 所有的Java虚拟机的执行引擎都是一致的:输入的是字节码文件,处理过程是字节码解析的等效过程,输出的是执行结果. 运行时栈帧结构 用于支持虚拟机进行方法调用和方 ...
- 深入理解Java虚拟机(字节码执行引擎)
深入理解Java虚拟机(字节码执行引擎) 本文首发于微信公众号:BaronTalk 执行引擎是 Java 虚拟机最核心的组成部分之一.「虚拟机」是相对于「物理机」的概念,这两种机器都有代码执行的能力, ...
- java编译后字节码解析
java编译后字节码解析 参考网摘: https://my.oschina.net/indestiny/blog/194260
- c#与java中byte字节的区别及转换方法
原文:c#与java中byte字节的区别及转换方法 在java中 byte的范围在 [-128,127] 在C#中 byte的范围在 [0,255] 所以 java程序与C#程序 进行数据传输的时 ...
随机推荐
- JAVA自学笔记(1)
JAVA入门级知识储备(一) 1.Scanner的欢乐接收 import java.util.Scanner; public class first { public static void main ...
- Linux下安装vim-plug报错:Failed to connect to raw.githubusercontent.com port 443: Connection refused
安装vim-plug时,输入以下命令: curl -fLo ~/.vim/autoload/plug.vim --create-dirs https://raw.githubusercontent.c ...
- Nginx 笔记(二)nginx常用的命令和配置文件
个人博客网:https://wushaopei.github.io/ (你想要这里多有) 1.nginx常用的命令 (1)启动命令 在/usr/local/nginx/sbin 目录下执行 ./ ...
- Java实现 LeetCode 403 青蛙过河
403. 青蛙过河 一只青蛙想要过河. 假定河流被等分为 x 个单元格,并且在每一个单元格内都有可能放有一石子(也有可能没有). 青蛙可以跳上石头,但是不可以跳入水中. 给定石子的位置列表(用单元格序 ...
- Java实现 LeetCode 191 位1的个数
191. 位1的个数 编写一个函数,输入是一个无符号整数,返回其二进制表达式中数字位数为 '1' 的个数(也被称为汉明重量). 示例 1: 输入:000000000000000000000000000 ...
- Java实现 LeetCode 80 删除排序数组中的重复项 II(二)
80. 删除排序数组中的重复项 II 给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素最多出现两次,返回移除后数组的新长度. 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O ...
- Java实现 LeetCode 5 最长回文子串
5. 最长回文子串 给定一个字符串 s,找到 s 中最长的回文子串.你可以假设 s 的最大长度为 1000. 示例 1: 输入: "babad" 输出: "bab&quo ...
- java 实现 蓝桥杯 算法提高 排列数
问题描述 0.1.2三个数字的全排列有六种,按照字母序排列如下: 012.021.102.120.201.210 输入一个数n 求0~9十个数的全排列中的第n个(第1个为0123456789). 输入 ...
- Linux 日志轮替
日志轮替包括两个方面的内容:切割日志文件,轮换日志文件 日志文件的命令规则 如果配置文件中有dateext参数,那么日志文件的后缀会是日期,例如:yum.log-20200424,这样,文件名不会重叠 ...
- PAT 换个格式输出整数
让我们用字母 B 来表示“百”.字母 S 表示“十”,用 12...n 来表示不为零的个位数字 n,换个格式来输出任一个不超过 3 位的正整数.例如 234 应该被输出为BBSSS1234,因为它有 ...