javassist庫介紹__API詳解

you些話 發表於 2020-11-21

處理類的基本用法

測試產生新的方法

//通過反射呼叫新生成的方法

修改已有的方法資訊,修改方法體的內容

//通過反射呼叫新生成的方法

屬性的操作

構造方法的操作

獲得註解的操作

package com.lzy.assist;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;

import javassist.CannotCompileException;
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
 * 
 *
 */
public class Demo02 {

	/**
	 * 處理類的基本用法
	 * @throws Exception 
	 */
	public static void  test01() throws Exception {
		ClassPool pool=ClassPool.getDefault();
		CtClass cc=pool.get("com.lzy.assist.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.lzy.assist.Emp");
		
		//CtMethod m=CtNewMethod.make("public int add(int a,int b){return a+b;}", cc);
		//49行與51-54行程式碼的效果一致
		CtMethod m=new CtMethod(CtClass.intType,"add",
				new CtClass[] {CtClass.intType,CtClass.intType},cc);
		m.setModifiers(Modifier.PUBLIC);//設定方法為public還是private或者其他型別
		m.setBody("{System.out.println(\"www.baidu.com\");return $1+$2;}");
		
		cc.addMethod(m);
		
		//通過反射呼叫新生成的方法
		Class clazz=cc.toClass();
		Object obj = clazz.getDeclaredConstructor().newInstance();  //通過呼叫Emp無參構造器,建立新的Emp物件
		Method method = clazz.getDeclaredMethod("add", int.class,int.class);
		Object result = method.invoke(obj, 200,300);
		System.out.println(result);
	}
	/**
	 * 修改已有的方法資訊,修改方法體的內容
	 * @param args
	 * @throws Exception
	 */
	public static void test03() throws Exception {
		ClassPool pool=ClassPool.getDefault();
		CtClass cc=pool.get("com.lzy.assist.Emp");
		
		CtMethod cm=cc.getDeclaredMethod("sayHello",new CtClass[] {CtClass.intType});
		cm.insertBefore("System.out.println($1);System.out.println(\"start!!!\");");//在sayHello()方法執行前執行該串程式碼
		cm.insertAt(9, "int b=3;System.out.println(\"b=\"+b);");//在第9行後執行該串程式碼
		cm.insertAfter("System.out.println(\"end!!!\");");在sayHello()方法執行後執行該串程式碼
		
		//通過反射呼叫新生成的方法
		Class clazz=cc.toClass();
		Object obj=clazz.getDeclaredConstructor().newInstance(); 
		Method method = clazz.getDeclaredMethod("sayHello", int.class);
		method.invoke(obj, 300);
	}
	/**
	 * 屬性的操作
	 * @param args
	 * @throws Exception 
	 * 
	 */
	public static void test04() throws Exception {
		ClassPool pool=ClassPool.getDefault();
		CtClass cc=pool.get("com.lzy.assist.Emp");
		
		
//		CtField f1 = CtField.make("private int salary;", cc);
		//96行與98-99行程式碼效果一致
		CtField f1 = new CtField(CtClass.intType,"salary",cc);
		f1.setModifiers(Modifier.PRIVATE);//設定屬性為public還是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.lzy.assist.Emp");
		
		CtConstructor[] cs = cc.getConstructors();
		for (CtConstructor c : cs) {
			System.out.println(c.getLongName());
		}
	}
	
	/**
	 * 獲得註解的操作
	 * @throws Exception
	 */
	public static void test06() throws Exception{
		 CtClass cc = ClassPool.getDefault().get("com.lzy.assist.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();
	}
}