尚学堂 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#程序 进行数据传输的时 ...
随机推荐
- 设计Dog类 代码参考
#include <iostream> #include <string> using namespace std; class Dog { private: string n ...
- # # # Vue的分环境打包
我们使用Vue-cli的默认环境是只有dev和prod两种环境,在开发中我们的项目一般是开发版.测试版.pre版.Prod版.我们一般是在源码中API地址中修改后然后打包. ###1.首先安装cros ...
- 跟着阿里学JavaDay06——Java基础语法(四)
一.方法 方法执行到return语句后,这个方法的执行就结束了,方法可以有返回值,但可以不用这个返回值.方法首先要定义,然后才能调用. public class TestMethod{ public ...
- C#/WPF/WinForm/.NET程序代码实现软件程序开机自动启动的两种常用方法的示例与源码下载带详细注释-源码代码-注册表方式-启动目录快捷方式
C#/WPF/WinForm/.NET程序代码实现软件程序开机自动启动的两种常用方法的示例与源码下载带详细注释-源码代码-注册表方式-启动目录快捷方式 C#实现自动启动的方法-两种方法 源码下载地址: ...
- Java实现 LeetCode 520 检测大写字母
520. 检测大写字母 给定一个单词,你需要判断单词的大写使用是否正确. 我们定义,在以下情况时,单词的大写用法是正确的: 全部字母都是大写,比如"USA". 单词中所有字母都不是 ...
- 洛谷P1255 数楼梯
题目描述 楼梯有N阶,上楼可以一步上一阶,也可以一步上二阶. 编一个程序,计算共有多少种不同的走法. 分析与代码 走n阶楼梯,无论是走一次走1阶还是2阶,总得迈出一步, 所以求n阶楼梯 ...
- 基于ABP做一个简单的系统——实战篇:1.项目准备
现阶段需要做一个小项目,体量很小,业务功能比较简单,就想到用最熟悉的.net来做,更何况现在.net core已经跨平台,也可以在linux服务器上部署.所以决定用.net core 3.1+mysq ...
- Spring源码之自动装配
我们使用Spring开发过程中经常会用到Autowired注解注入依赖的bean,这部分也是面试的热点问题之一.今天咱们一起来深入研究下自动注入的背后实现原理.首先上一个例子,如下所示: @RestC ...
- 智能家居巨头 Aqara 基于 KubeSphere 打造物联网微服务平台
背景 从传统运维到容器化的 Docker Swarm 编排,从 Docker Swarm 转向 Kubernetes,然后在 Kubernetes 运行 SpringCloud 微服务全家桶,到最终拥 ...
- lei muban
#include<iostream> using namespace std; template <typename T> class Operator{ public: T ...