真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

java中ASM框架有什么用

這篇文章主要為大家展示了“java中ASM框架有什么用”,內(nèi)容簡(jiǎn)而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學(xué)習(xí)一下“java中ASM框架有什么用”這篇文章吧。

創(chuàng)新互聯(lián)專(zhuān)注為客戶(hù)提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于成都做網(wǎng)站、網(wǎng)站設(shè)計(jì)、遼寧網(wǎng)絡(luò)推廣、小程序開(kāi)發(fā)、遼寧網(wǎng)絡(luò)營(yíng)銷(xiāo)、遼寧企業(yè)策劃、遼寧品牌公關(guān)、搜索引擎seo、人物專(zhuān)訪、企業(yè)宣傳片、企業(yè)代運(yùn)營(yíng)等,從售前售中售后,我們都將竭誠(chéng)為您服務(wù),您的肯定,是我們最大的嘉獎(jiǎng);創(chuàng)新互聯(lián)為所有大學(xué)生創(chuàng)業(yè)者提供遼寧建站搭建服務(wù),24小時(shí)服務(wù)熱線:028-86922220,官方網(wǎng)址:www.cdcxhl.com

簡(jiǎn)介

ASM是java字節(jié)碼操作框架,利用該框架可以達(dá)到動(dòng)態(tài)修改java運(yùn)行對(duì)象代碼的目的,也可以實(shí)現(xiàn)動(dòng)態(tài)代理等功能;

線程和棧幀

要了解ASM字節(jié)碼操作,先要熟悉jvm線程與棧幀結(jié)構(gòu),jvm開(kāi)辟一個(gè)線程,便會(huì)開(kāi)辟屬于這個(gè)線程虛擬機(jī)棧,本地方法棧,程序計(jì)數(shù)器,其主要作用如下:

  • 虛擬機(jī)棧:以棧幀為基本單位,一個(gè)棧幀的開(kāi)始地址代表一個(gè)方法的入口,棧幀里面有操作數(shù)棧,局部變量表,動(dòng)態(tài)鏈接,方法出口,其他信息;其說(shuō)明如下:

    • 操作數(shù)棧::用來(lái)存放需要cpu進(jìn)行計(jì)算的基本類(lèi)型和對(duì)象引用,以4個(gè)字節(jié)的slot為基本單位;

    • 局部變量表:存放當(dāng)前棧幀涉及到的變量表,以4個(gè)字節(jié)的slot為基本單位;

    • 動(dòng)態(tài)鏈接: 存放執(zhí)行常量池的引用,可以實(shí)現(xiàn)當(dāng)前方法的動(dòng)態(tài)鏈接;

    • 方法出口:用于方法的返回,可以是異常的發(fā)生,return操作指令等等;

  • 本地方法棧:類(lèi)似于虛擬機(jī)棧,但是保存的是java本地代碼庫(kù)的一些信息;

  • 程序計(jì)數(shù)器:保存該線程指令執(zhí)行位置,待下次調(diào)度時(shí)可以接著往下執(zhí)行;
    具體如下圖所示:

     

     

         

    線程虛擬機(jī)棧結(jié)構(gòu).png

基本類(lèi)型

java字節(jié)碼中的類(lèi)型表達(dá)和java代碼是不一樣的,在java字節(jié)碼中利用如下符號(hào)來(lái)表達(dá)基本類(lèi)型:

java類(lèi)型type含義
booleanZ布爾
charC字符
byteB字節(jié)
shortS短整型
intI整型
longJ長(zhǎng)整型
floatF浮點(diǎn)數(shù)
referenceL類(lèi)的引用
voidV
doubleD雙精度浮點(diǎn)型
ObjectLjava/lang/Object;對(duì)象
int[][I整型數(shù)組
Object[][][[Ljava/lang/Object;對(duì)象數(shù)組

注: L+className;代表某類(lèi)的引用(";"不能省略)

字節(jié)碼實(shí)例:

Java代碼字節(jié)碼表示注釋
double[][][[D
Object run(int i,double d,Thread t)(IDLjava/lang/Thread)Ljava/lang/Object;(方法參數(shù)字節(jié)碼類(lèi)型)方法返回參數(shù)類(lèi)型

字節(jié)碼指令操作

字節(jié)碼指令操作其實(shí)主要操作局部變量表和操作數(shù)棧,具體流程是:load局部變量到操作數(shù)棧,然后給cpu下達(dá)執(zhí)行指令,然后將操作數(shù)棧棧頂元素彈出,從而實(shí)現(xiàn)一個(gè)操作;
字節(jié)碼指令都有一定的格式:[type+]op["_"+value];

其中type根據(jù)基本類(lèi)型可以為:i(int 整數(shù)),s(short 短整數(shù)),b(byte 字節(jié)),c(char字符),l(long長(zhǎng)整數(shù)),d(double雙精度浮點(diǎn)數(shù)),f(float 浮點(diǎn)數(shù)),a(reference 引用);
value指的是操作數(shù),如果操作數(shù)為負(fù)數(shù)時(shí)需要添加'm"前綴,例如iconstant_m1表示將-1壓棧;如果操作數(shù)值超過(guò)一定大小,則會(huì)將該操作數(shù)存放在常量池,用#indexbyte表示其位置;
op指的是操作碼,通常用一個(gè)字節(jié)表示;

字節(jié)碼指令操作主要分為九大指令:

  • 加載和存儲(chǔ)指令:用于將數(shù)據(jù)在操作數(shù)棧和局部變量表來(lái)回傳輸;

  • 運(yùn)算指令:用于將操作數(shù)棧棧頂?shù)膬蓚€(gè)數(shù)值進(jìn)行運(yùn)算,然后重新放入操作數(shù)棧頂;

  • 類(lèi)型轉(zhuǎn)換指令:用于將兩個(gè)不同數(shù)值類(lèi)型進(jìn)行相互轉(zhuǎn)換;

  • 對(duì)象創(chuàng)建和訪問(wèn)指令: 用于創(chuàng)建對(duì)象和訪問(wèn)對(duì)象

  • 操作數(shù)棧管理指令:用于管理操作數(shù)棧,類(lèi)似普通棧管理

  • 控制轉(zhuǎn)移指令:用于讓jvm從指定位置的指令開(kāi)始執(zhí)行而不是控制下一條指令位置開(kāi)始執(zhí)行;

  • 方法調(diào)用和返回指令:用于方法調(diào)用和方法返回;

  • 異常處理指令:對(duì)jvm拋出的異常進(jìn)行處理指令;

  • 方法同步指令:用來(lái)控制不同線程對(duì)方法的同步控制;

加載和存儲(chǔ)指令

加載指令主要是將局部變量和常量壓入到操作數(shù)棧,具體指令有:

  • 常量壓棧指令,常量壓棧指令時(shí)根據(jù)常量所占字節(jié)大小劃分,指令如下:

    • constant:該常量字節(jié)大小為-1到5的數(shù)值,例如iconstant_0將整數(shù)0壓棧,lconstant_5將長(zhǎng)整數(shù)5壓棧;

    • bipush:將字節(jié)值為byte類(lèi)型的數(shù)值轉(zhuǎn)換為整型,然后壓棧(byte值大小為-128-127);

    • sipush:將字節(jié)值為short類(lèi)型的數(shù)值轉(zhuǎn)換為整型,然后壓棧(short值為-32768-32767);

    • ldc: 根據(jù)指定索引值(需要一個(gè)字節(jié)存儲(chǔ)的indexbyte)從常量池取出大小在-2147483648~2147483647的常量值,如int,float,Reference型常量值;

    • ldc_w:根據(jù)指定寬索引值(需要兩個(gè)字節(jié)存儲(chǔ)的索引值)從常量池取出如int,float,Reference等常量值進(jìn)行壓棧;

    • ldc2_w:根據(jù)指定寬索引值從常量池中取出如long,double等常量值進(jìn)行壓棧;
      如下圖:

       

       

      常量壓棧.png

       

      如上圖所示,其中32767表示操作數(shù)值,在[-32768,32767]之間是不會(huì)保存到常量池的,而超過(guò)這個(gè)值則需要利用indexbyte(#30,#35)代表的索引,去常量池中查找

  • load:將局部變量指定位置(具體值或者索引)處的對(duì)象壓棧;aload_0將局部變量表0處的引用類(lèi)型入棧,
    iload indexbyte將局部變量表中indexbyte表示的int類(lèi)型入棧;caload從char類(lèi)型數(shù)組中裝載指定項(xiàng)的值(先轉(zhuǎn)換為int類(lèi)型值,后壓棧)

  • store :將操作數(shù)棧棧頂值彈出并保存到局部變量表中;例如:istore_3將short,byte,char,int類(lèi)型保存到局部變量表3處根據(jù)類(lèi)型轉(zhuǎn)換,lstore [opNum] (opNum需大于3)則將long類(lèi)型保存到局部變量opNum處;dstore用來(lái)保存棧頂?shù)膁ouble類(lèi)型,fstore用來(lái)保存棧頂?shù)膄loat類(lèi)型;

如下圖所示:

加載存儲(chǔ)指令.png

運(yùn)算指令

運(yùn)算指令有以下幾種:

  • (T)add:將棧頂T類(lèi)型的兩個(gè)數(shù)值相加后入棧,T:float,int,short,long,double

  • (T)sub:將棧頂T類(lèi)型的兩個(gè)數(shù)值相減后入棧,T:float,int,short,long,double

  • (T)mul:將棧頂T類(lèi)型的兩個(gè)數(shù)值相乘后入棧,T:float,int,short,long,double

  • (T)div:將棧頂T類(lèi)型的兩個(gè)數(shù)值相除后入棧,T:float,int,short,long,double

  • (T)rem:將棧頂T類(lèi)型的兩個(gè)數(shù)值取模后入棧,T:float,int,short,long,double

  • (T)neg:將棧頂T類(lèi)型的取負(fù)后入棧,T:float,int,short,long,double

  • (T)iinc [indexbyte,constantbyte]:將整數(shù)值constbyte加到indexbyte指定的int類(lèi)型的局部變量中;

     

     

         

    運(yùn)算指令.png

  • (T)shl:算數(shù)左移后入棧,T為非浮點(diǎn)類(lèi)型的基本類(lèi)型;

  • (T)shr:算數(shù)左移后入棧,T為非浮點(diǎn)類(lèi)型的基本類(lèi)型;

  • (T)ushl:邏輯左移后入棧,T為非浮點(diǎn)類(lèi)型的基本類(lèi)型;

  • (T)ushr:邏輯右移后入棧,T為非浮點(diǎn)類(lèi)型的基本類(lèi)型;

  • (T)and:與操作,T為非浮點(diǎn)類(lèi)型的基本類(lèi)型;

  • (T)or:或操作,T為非浮點(diǎn)類(lèi)型的基本類(lèi)型;

  • (T)xor:異或操作,T為非浮點(diǎn)類(lèi)型的基本類(lèi)型;

類(lèi)型轉(zhuǎn)換指令

類(lèi)型轉(zhuǎn)換指令有以下幾種:

  • (T)2(V):將T基本類(lèi)型轉(zhuǎn)換成V基本類(lèi)型,如果是長(zhǎng)字節(jié)類(lèi)型轉(zhuǎn)換短字節(jié)類(lèi)型,則需要把高位字節(jié)截?cái)?;如l2i:將long轉(zhuǎn)換成int則會(huì)把高4個(gè)字節(jié)截?cái)嗪笫O碌乃膫€(gè)字節(jié)轉(zhuǎn)換成int;

對(duì)象創(chuàng)建和訪問(wèn)指令

對(duì)象創(chuàng)建和訪問(wèn)指令通常需要兩個(gè)操作數(shù)indexbyte1和indexbyte2

  • new :創(chuàng)建新的對(duì)象實(shí)例;

  • checkcast:強(qiáng)制類(lèi)型轉(zhuǎn)換;

  • instanceof:判斷是否類(lèi)實(shí)例;

  • getField:獲取類(lèi)實(shí)例字段值;

  • putField:給類(lèi)實(shí)例字段賦值;

  • getStatic:獲取類(lèi)靜態(tài)變量值;

  • putStatic:給類(lèi)靜態(tài)變量賦值;

  • newarray:創(chuàng)建基本類(lèi)型數(shù)組;

  • anewarray:創(chuàng)建引用類(lèi)型數(shù)組;

  • arraylength:獲取一維數(shù)組長(zhǎng)度;

操作數(shù)棧管理指令

字等于兩個(gè)字節(jié),半個(gè)slot,16位

  • nop: 空操作;

  • pop :彈出棧頂一個(gè)字長(zhǎng)數(shù)據(jù);

  • pop2:彈出棧頂兩個(gè)字長(zhǎng)的數(shù)據(jù);

  • dup:復(fù)制棧頂一個(gè)字長(zhǎng)的數(shù)據(jù),同時(shí)將該數(shù)據(jù)入棧;

  • dup_x1:復(fù)制棧頂一個(gè)字長(zhǎng)的數(shù)據(jù),同時(shí)彈出棧頂兩個(gè)字長(zhǎng)的數(shù)據(jù),然后再將復(fù)制的數(shù)據(jù)入棧,再將彈出的兩個(gè)字入棧;

  • dup_x2:復(fù)制棧頂一個(gè)字長(zhǎng)的數(shù)據(jù),同時(shí)彈出棧頂三個(gè)字長(zhǎng)的數(shù)據(jù),然后再將復(fù)制的數(shù)據(jù)入棧,再將彈出的三個(gè)字入棧;

  • dup2:復(fù)制棧頂兩個(gè)字長(zhǎng)的數(shù)據(jù),同時(shí)將該數(shù)據(jù)入棧;

  • dup2_x1:復(fù)制棧頂兩個(gè)字長(zhǎng)的數(shù)據(jù),同時(shí)彈出棧頂三個(gè)字長(zhǎng)的數(shù)據(jù),然后再將復(fù)制的數(shù)據(jù)入棧,再將彈出的三個(gè)字入棧;

  • dup2_x2:復(fù)制棧頂兩個(gè)字長(zhǎng)的數(shù)據(jù),同時(shí)彈出棧頂四個(gè)字長(zhǎng)的數(shù)據(jù),然后再將復(fù)制的數(shù)據(jù)入棧,再將彈出的四個(gè)字入棧;

  • swap:交換棧頂兩個(gè)字長(zhǎng)的數(shù)據(jù),Java指令中沒(méi)有提供交換兩個(gè)字長(zhǎng)為單位的交換指令;

控制轉(zhuǎn)移指令:

控制轉(zhuǎn)移指令分為跳轉(zhuǎn)指令和比較指令,無(wú)條件跳轉(zhuǎn)指令,表跳轉(zhuǎn)指令,異常跳轉(zhuǎn)指令;
跳轉(zhuǎn)指令:

  • ifeq:若棧頂int類(lèi)型為0則跳轉(zhuǎn);

  • ifne:若棧頂int類(lèi)型不為0則跳轉(zhuǎn);

  • iflt:若棧頂int類(lèi)型小于0則跳轉(zhuǎn);

  • ifle: 若棧頂int類(lèi)型小于等于0則跳轉(zhuǎn);

  • ifgt:若棧頂int類(lèi)型大于0則跳轉(zhuǎn);

  • ifge:若棧頂int類(lèi)型大于等于0則跳轉(zhuǎn);

  • if_icmpeq:若棧頂兩int類(lèi)型相等則跳轉(zhuǎn);

  • if_icmpne: 若棧頂兩int類(lèi)型相等則跳轉(zhuǎn);

  • if_icmplt:若棧頂int前小于后則跳轉(zhuǎn);

  • if_icpmle:若棧頂int前小于等于后則跳轉(zhuǎn);

  • if_icpmgt: 若棧頂int前大于后則跳轉(zhuǎn);

  • if_icpmge: 若棧頂int前大于等于后則跳轉(zhuǎn);

  • ifnull: 如棧頂引用為空則跳轉(zhuǎn);

  • ifnonnull:若棧頂引用不為空則跳轉(zhuǎn);

  • if_acmpeq:若棧頂兩引用相等則跳轉(zhuǎn);

  • if_acmpne: 若棧頂兩引用不相等則跳轉(zhuǎn);

比較指令:

  • (T)cmp:比較棧頂兩個(gè)T類(lèi)型大小,前者大,則1入棧;相等則0入棧;后者大則-1入棧;

  • (T)cmpl:比較棧頂兩個(gè)T類(lèi)型大小,前者大,則1入棧;相等則0入棧;后者大則-1入棧;有NAN存在,則-1入棧;

  • (T)cmpg:比較棧頂兩個(gè)T類(lèi)型大小,前者大,則1入棧;相等則0入棧;后者大則-1入棧;有NAN存在,則-1入棧;

無(wú)條件轉(zhuǎn)移指令:

  • goto :無(wú)條件轉(zhuǎn)移到指定位置;

  • goto_w:無(wú)條件轉(zhuǎn)移到指定位置(寬索引);

表跳轉(zhuǎn)指令:

  • tableswitch:通過(guò)索引訪問(wèn)跳轉(zhuǎn)表,并跳轉(zhuǎn);

  • lookupswitch: 通過(guò)健值訪問(wèn)跳轉(zhuǎn)表,并跳轉(zhuǎn);

異常跳轉(zhuǎn)指令:

  • athrow:拋出異常;

  • jsr:跳轉(zhuǎn)到指定程序;

  • jsr_w:跳轉(zhuǎn)到指定程序(寬索引);

  • ret:返回到指定程序;

方法調(diào)用和返回指令:

  • invokerspecial:指令用于調(diào)用一些需要特殊處理的實(shí)例方法,包括實(shí)例初始化方法、私有方法和父類(lèi)方法,編譯時(shí)綁定;

  • invokevirtual:指令用于調(diào)用對(duì)象的實(shí)例方法,根據(jù)對(duì)象的實(shí)際類(lèi)型進(jìn)行分派,運(yùn)行時(shí)綁定;

  • invokestatic:調(diào)用靜態(tài)方法;

  • invokeinterface:用以調(diào)用接口方法,在運(yùn)行時(shí)搜索一個(gè)實(shí)現(xiàn)了這個(gè)接口方法的對(duì)象,找出適合的方法進(jìn)行調(diào)用;

  • invokedynamic:用于處理新的方法分派:它允許應(yīng)用級(jí)別的代碼來(lái)確定執(zhí)行哪一個(gè)方法調(diào)用,只有在調(diào)用要執(zhí)行的時(shí)候,才會(huì)進(jìn)行這種判斷,從而達(dá)到動(dòng)態(tài)語(yǔ)言的支持,lambda方法實(shí)現(xiàn)就是依賴(lài)于該指令;

  • (T)return:方法退出指令,T表示返回類(lèi)型;
    關(guān)于invokespecial和invokevirtual如下圖:

     

     

         

    invokespecial和invokevirtual.png

同步方法指令:

  • monitorenter: 進(jìn)入并獲得對(duì)象監(jiān)視器;

  • monitorexit:退出并釋放對(duì)象監(jiān)視器;

以上是“java中ASM框架有什么用”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!


標(biāo)題名稱(chēng):java中ASM框架有什么用
分享地址:http://weahome.cn/article/iiesji.html

其他資訊

在線咨詢(xún)

微信咨詢(xún)

電話咨詢(xún)

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部