1. 程式人生 > >使用javassit操作執行時位元組碼檔案

使用javassit操作執行時位元組碼檔案

1、是什麼

Javassit是一個功能包,作用類似於java的反射,用於操作執行時位元組碼檔案,實現動態程式設計,但效能高於反射。

2、怎麼用?

首先需要獲取存放class檔案的容器ClassPool,根據全類名獲取一個CtClass物件,根據需要修改這個CtClass物件,如果.class檔案已經被JVM載入了,則需要先呼叫ctClass.stopPruning(true),最後使用位元組流將CtClass物件生成的位元組陣列寫到對應的.class檔案

3、程式碼例項

public void test_1(){ 
    ClassPool pool = ClassPool.getDefault();
    CtClass ctClass = pool.makeClass("com.czp.CtClassTest");
    ctClass.stopPruning(true);
    try { 
	    //自定義屬性
        ctClass.addField(CtField.make("private int age;", ctClass)); 
        ctClass.addMethod(CtMethod.make("public void setAge(int age){this.age = age;}", ctClass));
        ctClass.addMethod(CtMethod.make("public int getAge(){return this.age;}", ctClass)); 
        //獲取位元組陣列寫入到指定檔案
        byte[] byteArray = ctClass.toBytecode();
        FileOutputStream output = new FileOutputStream("F://czp/CtClassTest.class ");
        output.write(byteArray);                                        
        output.close();
		

        if(ctClass.isFrozen()){//如果class檔案被凍結,已經被jvm載入
            ctClass.defrost();//解凍
        }
		//在class Pool中獲取到對應.class檔案
        ctClass = pool.get("com.czp.CtClassTest ");
        //同上
        ctClass.addField(CtField.make("private String sex;", ctClass));
        ctClass.addField(CtField.make("private String name;", ctClass)); 
        byteArray = ctClass.toBytecode();
        output = new FileOutputStream("F://czp/CtClassTest.class");
        output.write(byteArray);
        output.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
}