java api知识串讲_Java知识点总结(动态字节码操作-Javassist的API使用)

Java知识点总结(动态字节码操作-Javassist的API使用)

@(Java知识点总结)[Java, 动态字节码操作]

参考文章:传送

操作示例:

public @interface Author {

String name();

int year();

}

@Author(name = "gs",year=2015)

public class Emp {

private int num;

private String name;

public Emp() {

}

public Emp(int num, String name) {

this();

this.num = num;

this.name = name;

}

public void sayHello(String name){

System.out.print("你好,");

}

public int getNum() {

return num;

}

public void setNum(int num) {

this.num = num;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

}

import java.lang.reflect.Method;

import java.lang.reflect.Modifier;

import java.util.Arrays;

import javassist.ClassPool;

import javassist.CtClass;

import javassist.CtConstructor;

import javassist.CtField;

import javassist.CtMethod;

import javassist.CtNewMethod;

import javassist.NotFoundException;

/**

* 测试 javassist 的 API

*

* @author Administrator

*

*/

public class Test11 {

// 通过类名加载已有的类

public static void test1(ClassPool pool, CtClass cc) {

try {

cc = pool.get("com.gs.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()); // 获取接口

} catch (Exception e) {

e.printStackTrace();

}

}

// 动态生成一个方法,并调用

public static void test2(ClassPool pool, CtClass cc) {

try {

/*当CtClass对象通过writeFile()、toClass()、toBytecode()转化为Class后,

* Javassist冻结了CtClass对象,因此,JVM不允许再次加载Class文件,所以不允许对其修改。

因此,若想对CtClass对象进行修改,必须对其进行解冻,通过defrost()方法进行*/

cc.defrost();

// 生成一个方法

CtMethod add = CtNewMethod.make("public int add(int a,int b){return $1+$2;}", cc);

// 生成一个方法

CtMethod subtraction = new CtMethod(CtClass.intType, "subtraction",

new CtClass[] { CtClass.intType, CtClass.intType }, cc);

subtraction.setModifiers(Modifier.PUBLIC);

subtraction.setBody("return $1-$2;");

cc.addMethod(add);

cc.addMethod(subtraction);

// 通过反射调用生成的方法

Class clazz = cc.toClass();

Emp emp = (Emp) clazz.newInstance();

// Method method = clazz.getDeclaredMethod("add", new

// Class[]{int.class,int.class});

Method method = clazz.getDeclaredMethod("subtraction", new Class[] { int.class, int.class });

Object result = method.invoke(emp, 200, 300);

System.out.println(result);

} catch (Exception e) {

}

}

// 方法体前面和后面加执行语句

public static void test3(ClassPool pool, CtClass cc) {

try {

cc.defrost();

CtMethod m1 = cc.getDeclaredMethod("sayHello", new CtClass[] { pool.get("java.lang.String") });

m1.insertBefore("System.out.println(\"方法体前面\");");

m1.insertAfter("System.out.println($1);");

// 通过反射调用生成的方法

Class clazz = cc.toClass();

Emp emp = (Emp) clazz.newInstance();

Method method = clazz.getDeclaredMethod("sayHello", new Class[] { String.class });

method.invoke(emp, "张三");

} catch (Exception e) {

e.printStackTrace();

}

}

// 生成属性和方法

public static void test4(ClassPool pool, CtClass cc) {

try {

// CtField.make("private double salary;", cc);

CtField field = new CtField(CtClass.doubleType, "salary", cc);

field.setModifiers(Modifier.PRIVATE);

cc.addField(field);

// cc.getDeclaredField("salary"); //获取属性

CtMethod method = CtNewMethod.getter("getSalary", field);

cc.addMethod(method);

CtMethod method2 = CtNewMethod.getter("setSalary", field);

cc.addMethod(method2);

} catch (Exception e) {

e.printStackTrace();

}

}

// 生成构造器

public static void test5(ClassPool pool, CtClass cc) {

try {

cc.defrost();

CtConstructor[] cs = cc.getConstructors();

for (CtConstructor c : cs) {

System.out.println(c.getLongName());

c.insertAfter("System.out.println(\"可以在构造器前后加代码\");");

}

} catch (Exception e) {

e.printStackTrace();

}

}

// 注解操作

public static void test6(ClassPool pool, CtClass cc) {

try {

cc.defrost();

Object[] annotations = cc.getAnnotations();

Author author = (Author) annotations[0];

System.out.println("name:" + author.name() + ",year:" + author.year());

} catch (Exception e) {

e.printStackTrace();

}

}

public static void main(String[] args) {

ClassPool pool = ClassPool.getDefault();

CtClass cc = null;

try {

cc = pool.get("com.gs.Emp");

} catch (NotFoundException e) {

e.printStackTrace();

}

test1(pool, cc);

//test2(pool, cc);

test3(pool, cc);

test5(pool, cc);

test6(pool, cc);

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值