<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    kooyee ‘s blog

    開源軟件, 眾人努力的結(jié)晶, 全人類的共同財(cái)富
    posts - 103, comments - 55, trackbacks - 0, articles - 66
       :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

    作者簡(jiǎn)介


    薛谷雨,NORDSAN(北京)信息科技開發(fā)有限公司高級(jí)JAVA研發(fā)工程師,正致力于企業(yè)級(jí)異構(gòu)數(shù)據(jù)交換的服務(wù)器產(chǎn)品的研發(fā),在J2EE和WEB SERVICE方面有較為豐富的開發(fā)經(jīng)驗(yàn),您可以通過rainight@126.com與他聯(lián)系。

    前言


    代碼生成器(code generator,CG),顧名思義就是生成代碼的工具。有了它,你就可以從一組簡(jiǎn)單的設(shè)定或者數(shù)據(jù)庫(kù)設(shè)計(jì)中獲得幾百、幾千行代碼。如果不采用這項(xiàng)技術(shù)的話,開發(fā)者就不得不花上幾個(gè)小時(shí)或者幾天的時(shí)間來手工編寫這些代碼。另一方面,優(yōu)秀的開發(fā)工具為了提供其獨(dú)特的功能或者屏蔽一些容易出錯(cuò)的細(xì)節(jié),也往往采用代碼生成技術(shù)為使用者提供一個(gè)程序的模板框架,其目的也是為了提高編程的效率。以上觀點(diǎn)僅是對(duì)代碼生成器的一般理解,換句話說,這似乎是一個(gè)可有可無的東西,沒有它,不過是多費(fèi)一些人工而已。然而,本文要介紹的這套名為ASM的JAVA工具類的功能非同小可,它可以生成JAVA字節(jié)碼,也就是class文件。你可以在應(yīng)用程序中根據(jù)情況動(dòng)態(tài)生成各式各樣的class,然后就調(diào)用,達(dá)到一種近乎上帝造物般的神奇。心動(dòng)不如行動(dòng),如果你也想在自己的開發(fā)中引入這一超前的編程技術(shù),請(qǐng)看此文。

    小巧而神奇的ASM


    ASM是一套JAVA字節(jié)碼生成架構(gòu)。它可以動(dòng)態(tài)生成二進(jìn)制格式的stub類或其他代理類,或者在類被JAVA虛擬機(jī)裝入內(nèi)存之前,動(dòng)態(tài)修改類。ASM 提供了與 BCEL( http://jakarta.apache.org/bcel )和SERP( http://serp.sourceforge.net/ )相似的功能,只有22K的大小,比起350K的BCEL和150K的SERP來說,是相當(dāng)小巧的,并且它有更高的執(zhí)行效率,是BCEL的7倍,SERP的11倍以上。ASM一貫的設(shè)計(jì)思想就是將其應(yīng)用于動(dòng)態(tài)生成領(lǐng)域,因此小巧和快捷一直是這個(gè)產(chǎn)品的設(shè)計(jì)和實(shí)現(xiàn)的指導(dǎo)思想。

    此產(chǎn)品由法國(guó)電信公司的研發(fā)工程師Eric Bruneton負(fù)責(zé)。從2002年7月ASM的第一個(gè)版本發(fā)布至今,此產(chǎn)品已經(jīng)升級(jí)了五次,日臻完美。到目前為止,ASM最新的版本是1.3.5,你可以去 http://asm.objectweb.org/ 下載。

    ASM的最終目標(biāo)是創(chuàng)建一個(gè)生成工具,可以被用來執(zhí)行對(duì)任何類的處理操作(不像一些工具,比如Javassit,它只支持預(yù)先定義的類操作,然而在許多場(chǎng)合這一功能是有局限性的)。

    JAVA的CLASS文件格式


    要想駕馭ASM,先要了解一下JAVA的CLASS文件格式。JAVA的CLASS文件通常是樹型結(jié)構(gòu)。根節(jié)點(diǎn)包含以下元素:

    • ConstantPool:符號(hào)表;
    • FieldInfo:類中的成員變量信息;
    • MethodInfo:類中的方法描述;
    • Attribute:可選的附加節(jié)點(diǎn)。

    FieldInfo節(jié)點(diǎn)包含成員變量的名稱,諸如public,private,static等的標(biāo)志。ConstantValue屬性用來存儲(chǔ)靜態(tài)的不變的成員變量的值。Deprecated和Synthetic被用來標(biāo)記一個(gè)成員變量是不被推薦的或由編譯器生成的。

    MethodInfo節(jié)點(diǎn)包含方法的名稱,參數(shù)的類型和和它的返回值,方法是公有的,私有的或靜態(tài)的等標(biāo)志。MethodInfo包含可選的附加屬性,其中最重要的是Code屬性,它包含非抽象的方法的代碼。Exceptions屬性包含方法將拋出的Exception的名稱。Deprecated和Synthetic屬性的信息同上面的FieldInfo的定義一樣。

    根節(jié)點(diǎn)的可選屬性有SourceFile,InnerClasses和Deprecated。SourceFile用來存儲(chǔ)被編譯成字節(jié)碼的源代碼文件的原始名稱;InnerClasses存儲(chǔ)內(nèi)部類的信息。由于這些屬性的存在,java 的類格式是可以擴(kuò)展的,也就是說可以在一個(gè)class中附加一些非標(biāo)準(zhǔn)的屬性, java虛擬機(jī)會(huì)忽略這些不可識(shí)別的屬性,正常的加載這個(gè)class。

    ConstantPool是一個(gè)由數(shù)字或字符串常量的索引組成的隊(duì)列,或由此類的樹的其他節(jié)點(diǎn)引用的,由其他對(duì)象創(chuàng)建的被引用常量的索引組成的隊(duì)列。這個(gè)表的目標(biāo)是為了減少冗余。例如,F(xiàn)ieldInfo節(jié)點(diǎn)不包含節(jié)點(diǎn)的名稱,只包含它在這一表中的索引。同樣的,GETFIELD和PUTFIELD不直接包含成員變量的名稱,只包含名稱的索引。

    精通ASM


    Asm架構(gòu)整體都圍繞著兩個(gè)接口,即ClassVisitor 和 CodeVisitor,它們能訪問每個(gè)類的方法,成員變量,包含在每個(gè)方法中的字節(jié)碼指令。ClassReader用來讀取class文件;ClassWriter類用來寫生成的Class文件。

    為了修改已經(jīng)存在的class,你必須使用分析class文件的ClassReader,類的修正器和寫class文件的ClassWriter。類的修正器就是一個(gè)ClassVisitor,它可以委派一部分工作到其他的ClassVisitor,但是為了實(shí)現(xiàn)預(yù)期的修改步驟,它將改變一些參數(shù)的值,或者調(diào)用一些其他方法。為了比較容易的實(shí)現(xiàn)這種類的修正器,ASM提供了一個(gè)ClassAdapter和CodeAdapter,這兩個(gè)適配器類分別實(shí)現(xiàn)了ClassVistor和CodeVistor接口。

    HelloWorld,體驗(yàn)造類的神奇


    下面是一個(gè)應(yīng)用ASM動(dòng)態(tài)生成字節(jié)碼的類,并調(diào)用其中方法的完整的HelloWorld 程序,程序的功能是動(dòng)態(tài)生成一個(gè)Example.class類,并實(shí)例化一個(gè)Example對(duì)象,調(diào)用對(duì)象的main函數(shù),在屏幕上打印出"Hello world!"


    import org.objectweb.asm.*;
    import java.lang.reflect.*;
    import java.io.FileOutputStream;

    public class Helloworld extends ClassLoader implements Constants {

      
    public static void main (final String args[]) throws Exception {

        
    /*
         * 此程序?qū)⑸梢粋€(gè)class,對(duì)應(yīng)的java源代碼是:
         *
         * public class Example {
         *   public static void main (String[] args) {
         *     System.out.println("Hello world!");
         *   }
         * }
         *
         
    */


        
    // 創(chuàng)建一個(gè)ClassWriter
        ClassWriter cw = new ClassWriter(false);
        cw.visit(ACC_PUBLIC, 
    "Example""java/lang/Object"nullnull);

        
    // 創(chuàng)建一個(gè) MethodWriter
        CodeVisitor mw = cw.visitMethod(ACC_PUBLIC, """()V"null);
        
    // 推入 'this' 變量
        mw.visitVarInsn(ALOAD, 0);
        
    //  創(chuàng)建父類的構(gòu)造函數(shù)
        mw.visitMethodInsn(INVOKESPECIAL, "java/lang/Object""""()V");
        mw.visitInsn(RETURN);
        
    // 這段代碼使用最多一個(gè)棧元素和一個(gè)本地變量
        mw.visitMaxs(11);

        
    // 為main方法創(chuàng)建一個(gè)MethodWriter
        mw = cw.visitMethod(
          ACC_PUBLIC 
    + ACC_STATIC, "main""([Ljava/lang/String;)V"null);
        
    // 使用System類的out成員類
        mw.visitFieldInsn(
          GETSTATIC, 
    "java/lang/System""out""Ljava/io/PrintStream;");
        
    // pushes the "Hello World!" String constant
        mw.visitLdcInsn("Hello world!");
        
    // 調(diào)用System.out的'println' 函數(shù)
        mw.visitMethodInsn(
          INVOKEVIRTUAL, 
    "java/io/PrintStream""println""(Ljava/lang/String;)V");
        mw.visitInsn(RETURN);
        
    // 這段代碼使用最多兩個(gè)棧元素和兩個(gè)本地變量
        mw.visitMaxs(22);

        
    // 生成字節(jié)碼形式的類
        byte[] code = cw.toByteArray();

        FileOutputStream fos 
    = new FileOutputStream("Example.class");
        
    //寫文件
        fos.write(code);
        
    //關(guān)閉輸出流
        fos.close();

        
    //實(shí)例化剛剛生成的類
        Helloworld loader = new Helloworld();
        Class exampleClass 
    = loader.defineClass("Example", code, 0, code.length);

        
    // 使用動(dòng)態(tài)生成的類打印 'Helloworld'
        Method main = exampleClass.getMethods()[0];
        main.invoke(
    nullnew Object[] {null});
      }

    }

    主站蜘蛛池模板: 免费观看激色视频网站(性色)| 久久精品免费大片国产大片 | 免费女人18毛片a级毛片视频| 亚洲国产成人久久77| 免费无码一区二区三区| 亚洲国产精品国自产拍电影| 久久午夜无码免费| 亚洲欧洲美洲无码精品VA| 亚洲免费观看视频| 亚洲欧洲综合在线| 免费国产黄线在线观看| 亚洲jizzjizz少妇| 亚洲国产精品日韩| 美女无遮挡拍拍拍免费视频| 亚洲va无码专区国产乱码| 2021在线永久免费视频| 亚洲人成色99999在线观看| 四只虎免费永久观看| 黄色网址免费在线观看| 亚洲天堂中文字幕| 成人午夜大片免费7777| 深夜a级毛片免费无码| 亚洲av中文无码乱人伦在线r▽ | 亚洲第一区精品日韩在线播放| 美女视频黄a视频全免费网站色 | 日日麻批免费40分钟日本的| 亚洲国产精品久久久久秋霞小| 国产免费av一区二区三区| 两性色午夜视频免费播放| 亚洲综合色一区二区三区小说| 两性刺激生活片免费视频| 精品一区二区三区无码免费直播| 亚洲区小说区激情区图片区| 5555在线播放免费播放| 亚洲av成本人无码网站| 亚洲午夜久久久久久久久电影网| AV大片在线无码永久免费| 无遮挡免费一区二区三区| 亚洲AV成人精品网站在线播放| 天天摸天天碰成人免费视频| 97国免费在线视频|