1. 程式人生 > >位元組碼操作_javassist庫_動態建立新類_屬性_方法_構造器_API詳解JAVA216-217

位元組碼操作_javassist庫_動態建立新類_屬性_方法_構造器_API詳解JAVA216-217

來源:http://www.bjsxt.com/
一、S02E216_01位元組碼操作_javassist庫、介紹、動態建立新類、屬性、方法、構造器

位元組碼操作
位元組碼操作

常見的位元組碼操作類庫
常見的位元組碼操作類庫

JAVAssist庫
JAVAssist庫

JAVAssist庫

package com.test.javassist;

import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtConstructor;
import javassist.CtField;
import
javassist.CtMethod; /** * 測試使用javassist生成一個新的類 */ public class Demo01 { public static void main(String[] args) throws CannotCompileException, Exception { ClassPool pool = ClassPool.getDefault(); CtClass cc = pool.makeClass("com.test.bean.Emp"); //建立屬性 CtField f1 = CtField.make("private int empno;"
,cc); CtField f2 = CtField.make("private String ename;",cc); cc.addField(f1); cc.addField(f2); //建立方法 CtMethod m1 = CtMethod.make("public int getEmpno(){return empno;}", cc); CtMethod m2 = CtMethod.make("public void setEmpno(){this.empno = empno;}", cc); cc.addMethod(m1); cc.addMethod(m2); //新增構造器
CtConstructor constructor = new CtConstructor(new CtClass[]{CtClass.intType, pool.get("java.lang.String")},cc); constructor.setBody("{this.empno = empno; this.ename = ename;}"); cc.addConstructor(constructor); cc.writeFile("g:/java/test");//將上面構造好的類寫入到指定的工作空間中 System.out.println("生成類,成功!"); } }

使用XJad反編譯後生成的.java檔案

// Decompiled by Jad v1.5.8e2. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://kpdus.tripod.com/jad.html
// Decompiler options: packimports(3) fieldsfirst ansi space 
// Source File Name:   Emp.java

package com.test.bean;


public class Emp
{

    private int empno;
    private String ename;

    public int getEmpno()
    {
        return empno;
    }

    public void setEmpno()
    {
        empno = empno;
    }

    public Emp(int i, String s)
    {
        empno = empno;
        ename = ename;
    }
}

一、S02E217_01位元組碼操作javaassist庫介紹_API詳解

方法操作

屬性操作

構造方法操作

侷限性

package com.test.javassist;

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;
/**
 * 測試javassist的API
 */
public class Demo2 {
    public static void main(String[] args) throws Exception {
        test06();
    }
    /**
     * 處理類的基本用法
     * @throws Exception 
     */
    public static void test01() throws Exception{
        ClassPool pool = ClassPool.getDefault();
        CtClass cc = pool.get("com.test.javassist.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());//獲取介面
    }
    /**
     * 測試產生新的方法
     */
    public static void test02() throws Exception{
        ClassPool pool = ClassPool.getDefault();
        CtClass cc = pool.get("com.test.javassist.Emp");//獲取已有的類
        //CtMethod m = CtNewMethod.make("public int add(int a,int b){return a+b;}", cc);
        //另一種方式,引數:返回型別,方法名,可變引數型別,CtClass物件
        CtMethod m = new CtMethod(CtClass.intType, "add", 
                new CtClass[]{CtClass.intType,CtClass.intType}, cc);

        m.setModifiers(javassist.Modifier.PUBLIC);
        m.setBody("{System.out.println(\"返回方法體中的列印資訊\");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.test.javassist.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);
    }
    /**
     * 測試產生新的屬性
     */
    public static void test04() throws Exception{
        ClassPool pool = ClassPool.getDefault();
        CtClass cc = pool.get("com.test.javassist.Emp");//獲取已有的類

        //CtField f1 = CtField.make("private int salary;", cc);
        //另一種方式
        CtField f1 = new CtField(CtClass.intType, "salary",cc);
        f1.setModifiers(Modifier.PRIVATE);
        cc.addField(f1);

        //cc.getDeclaredField("salary");//獲取指定的屬性
        //另一種方式
        cc.addMethod(CtNewMethod.getter("getSalary", f1));
        cc.addMethod(CtNewMethod.getter("setSalary", f1));

        //通過反射呼叫,省略。。。
    }
    /**
     * 測試構造器
     */
    public static void test05() throws Exception{
        ClassPool pool = ClassPool.getDefault();
        CtClass cc = pool.get("com.test.javassist.Emp");//獲取已有的類

        CtConstructor[] cs = cc.getConstructors();
        for (CtConstructor c : cs) {
            System.out.println(c.getLongName());
        }
    }
    /**
     * 測試註解
     */
    public static void test06() throws Exception{
        ClassPool pool = ClassPool.getDefault();
        CtClass cc = pool.get("com.test.javassist.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);
    }
}

javabean

package com.test.javassist;

@Author(name = "test",year= 2016)
public class Emp {
    private int empNo;
    private String empName;

    public Emp() {
    }
    public Emp(int empNo, String empName) {
        super();
        this.empNo = empNo;
        this.empName = empName;
    }

    public int getEmpNo() {
        return empNo;
    }
    public void setEmpNo(int empNo) {
        this.empNo = empNo;
    }
    public String getEmpName() {
        return empName;
    }
    public void setEmpName(String empName) {
        this.empName = empName;
    }

    public void sayHello(int a){
        System.out.println("sayHello," + a);
    }
}

註解

package com.test.javassist;

public @interface Author {
    String name();
    int year();
}

相關推薦

位元組操作_javassist_動態建立_屬性_方法_構造_APIJAVA216-217

來源:http://www.bjsxt.com/ 一、S02E216_01位元組碼操作_javassist庫、介紹、動態建立新類、屬性、方法、構造器 位元組碼操作 常見的位元組碼操作類庫 JAVAssist庫 package com

尊重原創>> 在html中建立標籤和屬性方法

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <s

Java學習之動態編譯--位元組操作--javassist

一、位元組碼操作 1.Java動態性的兩種常見實現方式: 位元組碼操作反射 2.執行時操作位元組碼可以實現如下功能: 動態生成新的類動態改變某個類的結構(新增/刪除/修改 新的屬性/方法) 3.優勢: 比反射開銷小,效能高Javaasist效能高於反射,低於ASM 二、常見

Android中使用Java開源Javassist動態建立位元組的學習研究

研究該內容想要達到的目的: 通過Javassist動態建立位元組碼特性在Android專案中執行時生成.dex檔案供Android程式呼叫。 Javassist簡介: Javassist是一個開源的分析、編輯和建立Java位元組碼的類庫。它是針對JAV

[譯]深入位元組操作:使用ASM和Javassist建立稽核日誌

深入位元組碼操作:使用ASM和Javassist建立稽核日誌 在堆疊中使用Spring和Hibernate,您的應用程式的位元組碼可能會在執行時被增強或處理。 位元組碼是Java虛擬機器(JVM)的指令集,所有在JVM上執行的語言都必須最終編譯為位元組碼。

位元組操作Javassist

一:建立新類: package com.chen.Base_Points; import javassist.ClassPool; import javassist.CtClass; import javassist.CtConstructor; import javas

Java位元組操作Javassist概述

Javassist(Java Programming Assistant)是一款編輯Java位元組碼的類庫。能夠在執行時定義新的Java類,在JVM載入類檔案時修改類的定義。 Javassist類庫提

關於360外掛化Replugin Activity動態修改父位元組操作

開發十年,就只剩下這套架構體系了! >>>   

8.5(java學習筆記)8.5 位元組操作(javassist)

一、javassist   javassist讓我們操作位元組碼更加簡單,它是一個類庫,允許我們修改位元組碼。它允許java程式動態的建立、修改類。   javassist提供了兩個層次的API,基於原始碼級別的和位元組碼級別的。     二、javassist建立類   1.獲取類池

java的動態性------Java位元組操作

常見的位元組碼操作類庫BECL :是java classing廣泛使用的一種框架,可以深入理解JVM組合語言,難學,需要一些JVM底層指令ASM :輕量級的java位元組碼操作框架,直接涉及JVM底層操作和指令CGLIB  :是基於ASM的的實現,強大效能高Javassist

二維操作第三方

下載地址 http://zxingnet.codeplex.com/downloads/get/824664 1.在http://zxingnet.codeplex.com/站點上下載ZXing .Net的第三方庫 2.新建一個WPF工程 3.引入zxing.d

java 位元組操作(javassist)

用javassist生成一個類(位元組碼檔案) /** * 使用javassist生成一個新的類 * @author L J */ public class JavassistDemo { public static void main(Stri

JAVA 位元組操作利器javassist

1、簡介 javassist是一個開源的分析、編輯和建立java位元組碼的類庫。不需要了解虛擬機器指令,就能動態生成類或者改變類的結構。 2、下載 (2)使用的版本是javassist-3.18.0-GA。 Javassist是一個執行位元組碼操作的強而有力

通過位元組看原理,帶你去找kotlin中的static方法

kotlin在被欽定為Android的官方開發語言後,越來越多的Android開發者投向kotlin的懷抱。儘管kotlin相容Java,但在使用上還是有很大不同的,就像static關鍵字,我們可以用companion object來替代static,當我們用反射去呼叫時,會發現呼叫時並不像static

MEF動態建立的例項

 MEF的基本概念不再贅述,不瞭解的朋友可以去MEF官網一探究竟。 本文主要分享在MEF中動態建立新例項的三種方法。 你可能會說,建立新的例項有什麼可說的,直接new SomeClass()不就可以了?確實可以,但是那樣會造成系統耦合度過高,不利於程式碼的維護和擴充套件。M

【代優化】考慮使用靜態工廠方法取代構造

ava tracking 什麽事 依據 mod true data -m span 靜態工廠方法與設計模式中的工廠方法模式不同,和設計模式中的工廠方法模式不直接相應。 使用靜態工廠方法比構造器的優勢: 第一、靜態工廠方法是有名稱的,而構造器是通過

MySQL數據修改數據表型(引擎)的方法

col table code 分享圖片 class size image color sql MySQL數據庫使用事務,相關數據表必須為InnoDB引擎 查看數據表狀態: SHOW TABLE STATUS FROM wawa WHERE NAME=‘ww_invite_

深入了以太坊虛擬機第3部分——動態數據型的表示方法

值類型 大於 tor a20 UNC 很多 posit res link Solidity提供了在其他編程語言常見的數據類型。除了簡單的值類型比如數字和結構體,還有一些其他數據類型,隨著數據的增加可以進行動態擴展的動態類型。動態類型的3大類: 映射(Mappings):

Java物件學習之建立物件——使用靜態工廠方法代替構造缺點

最近學習Android知識,發現Java好多的基礎知識運用的真的很一般,所以決定在重新梳理一下,現在Kotlin也來了,在Android之路上,留給我看Java的時間不多了。       靜態我們就來簡單介紹一下,使用靜態工廠方法建立物件相較於構造器建立的物件的優缺

Java物件學習之建立物件——使用靜態工廠方法代替構造優點(四)

最近學習Android知識,發現Java好多的基礎知識運用的真的很一般,所以決定在重新梳理一下,現在Kotlin也來了,在Android之路上,留給我看Java的時間不多了。       靜態我們就來簡單介紹一下,使用靜態工廠方法建立物件相較於構造器建立的物件的優缺