亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何基于javassist進行動態編程

發布時間:2020-07-27 14:16:37 來源:億速云 閱讀:236 作者:小豬 欄目:編程語言

小編這次要給大家分享的是如何基于javassist進行動態編程,文章內容豐富,感興趣的小伙伴可以來了解一下,希望大家閱讀完這篇文章之后能夠有所收獲。

今天在研究dubbo時,發現一個新的知識點,可以使用javassist包進行動態編程,hibernate也使用該包進行編程。晚上百度了很多資料,將它的特性以代碼的形式展現出來。

package com.zhi.demo;

import java.lang.reflect.Field;

import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtConstructor;
import javassist.CtField;
import javassist.CtMethod;
import javassist.CtNewConstructor;
import javassist.CtNewMethod;
import javassist.Loader;
import javassist.Modifier;
import javassist.bytecode.AccessFlag;

/**
 * Javassist動態編程測試
 *
 * @date 2019年03月11日23:00:33
 *
 */
public class JavassistTest {
  public static void main(String[] args) {
    try {
      test();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  private static void test() throws Exception {
    System.out.println("-------------------新增類------------------");
    ClassPool pool = ClassPool.getDefault();
    // 創建類
    CtClass ct = pool.makeClass("com.zhi.Person");
    // 讓類實現Cloneable接口
    ct.setInterfaces(new CtClass[] { pool.makeInterface("java.lang.Cloneable") });

    // 添加一個int類型的共有屬性
    CtField fieldId = new CtField(CtClass.intType, "id", ct);
    fieldId.setModifiers(AccessFlag.PUBLIC);
    ct.addField(fieldId);

    // 添加一個默認構造器
    CtConstructor constructor1 = CtNewConstructor.make("public Person(){this.id=1;}", ct);
    ct.addConstructor(constructor1);

    // 添加方法
    CtMethod helloM = CtNewMethod
        .make("public void hello(String des){System.out.println(\"執行hello方法,\"+des+\",我的id是\"+this.id);}", ct);
    ct.addMethod(helloM);

    // 將生成的.class文件保存到磁盤
    ct.writeFile();

    // 加載目標類,可用ct.toClass()或new Loader(pool).loadClass()
    Class<&#63;> clazz = ct.toClass();
//    Class<&#63;> clazz = new Loader(pool).loadClass("com.zhi.Person");

    // 輸出類基本信息
    System.out.println("包名:" + clazz.getPackageName());
    System.out.println("類名:" + clazz.getName());
    System.out.println("簡要類名:" + clazz.getSimpleName());
    System.out.println("限定符:" + Modifier.toString(clazz.getModifiers()));
    System.out.println("繼承類:" + clazz.getSuperclass().getName());
    Field[] fields = clazz.getDeclaredFields();
    for (Field field : fields) {
      System.out.println("屬性名稱:" + field.getName() + ",屬性類型:" + field.getType() + ",限定符:"
          + Modifier.toString(field.getModifiers()));
    }

    // 構造一個對象,并執行hello方法
    Object ob = clazz.getDeclaredConstructor().newInstance();
    clazz.getMethod("hello", String.class).invoke(ob, "張三");

    // 解凍(執行toClass后會自動凍結)
    ct.defrost();

    System.out.println("-------------------修改類------------------");

    // 添加一個String類型的私有屬性
    CtField fieldName = new CtField(pool.get(String.class.getName()), "name", ct);
    fieldName.setModifiers(AccessFlag.PRIVATE);
    ct.addField(fieldName);

    // 添加帶參的構造函數
    CtConstructor constructor2 = new CtConstructor(new CtClass[] { pool.get(String.class.getName()) }, ct);
    constructor2.setModifiers(Modifier.PUBLIC);
    constructor2.setBody("{this.name=$1;}");
    ct.addConstructor(constructor2);

    ct.addMethod(CtNewMethod.make("public void setName(String name){this.name=name;}", ct));
    ct.addMethod(CtNewMethod.make("public String getName(){return this.name;}", ct));

    ct.writeFile();

    // 加載類,若前面已用ct.toClass()進行加載,則這里不能再用ct.toClass()加載,否則會出錯,同一個加載不能2次加載同一個類
    clazz = new Loader(pool).loadClass("com.zhi.Person");

    fields = clazz.getDeclaredFields();
    for (Field field : fields) {
      System.out.println("屬性名稱:" + field.getName() + ",屬性類型:" + field.getType() + ",限定符:"
          + Modifier.toString(field.getModifiers()));
    }

    ob = clazz.getDeclaredConstructor(String.class).newInstance("馬云");
    System.out.println("執行getName方法得到的值為:" + clazz.getMethod("getName").invoke(ob));
  }
}

執行上面代碼輸出結果為:

-------------------新增類------------------
包名:com.zhi
類名:com.zhi.Person
簡要類名:Person
限定符:public
繼承類:java.lang.Object
屬性名稱:id,屬性類型:int,限定符:public
執行hello方法,張三,我的id是1
-------------------修改類------------------
屬性名稱:id,屬性類型:int,限定符:public
屬性名稱:name,屬性類型:class java.lang.String,限定符:private
執行getName方法得到的值為:馬云

說明:

$0,$1,$2:分別代表this,第一個參數,第二個參數

$r:方法返回值的類型。

$_:方法返回值

依賴包

<dependency>
  <groupId>org.javassist</groupId>
  <artifactId>javassist</artifactId>
  <version>3.24.1-GA</version>
</dependency>

看完這篇關于如何基于javassist進行動態編程的文章,如果覺得文章內容寫得不錯的話,可以把它分享出去給更多人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

伊宁市| 南澳县| 平武县| 呼和浩特市| 正阳县| 乐安县| 乳山市| 曲周县| 库尔勒市| 年辖:市辖区| 东海县| 鄯善县| 上高县| 镇雄县| 焉耆| 达拉特旗| 怀化市| 礼泉县| 吐鲁番市| 阳原县| 大丰市| 上饶县| 凭祥市| 雷波县| 永丰县| 缙云县| 讷河市| 鄂尔多斯市| 柘荣县| 沛县| 宿松县| 邢台市| 富平县| 光泽县| 扎兰屯市| 同心县| 邵阳县| 孟村| 蓝山县| 威宁| 德安县|