五月天青色头像情侣网名,国产亚洲av片在线观看18女人,黑人巨茎大战俄罗斯美女,扒下她的小内裤打屁股

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

Java ASM詳解:模塊

2022-10-18 00:53 作者:Nickid2018  | 我要投稿

在前兩篇專欄中我們討論了各種類的結(jié)構(gòu),將各種類組織一起它們就組成了模塊(Module)。

模塊的定義

模塊是在 Java 9 中引入的,它在module-info.java文件中定義。這個(gè)文件的內(nèi)容是一個(gè)模塊的描述,下面就是一個(gè)例子:

上面的代碼聲明了一個(gè)模塊,名稱為 JavaASMTest,并依賴模塊 org.objectweb.asm。

在模塊中,我們可以定義以下信息:

  1. requires 語句,它代表了這個(gè)模塊需要依賴于什么其它的模塊。所有的模塊都隱式定義了requires java.base。
    requires 語句可以使用 static 修飾符,代表靜態(tài)依賴。這種依賴在編譯期是必須的,但是在運(yùn)行時(shí)可以不存在。
    requires 語句也可以使用 transitive 修飾符,它代表了依賴此模塊的模塊將隱式獲得對(duì)本模塊依賴的模塊的可讀性。舉一個(gè)例子:如果 A 依賴于 B,B 依賴于 C,那么 C 對(duì) A 來說不可讀,除非 A 顯式定義 requires C;但是加上這個(gè)關(guān)鍵詞,C 將對(duì) A 可讀。

  2. exports 語句,它代表了模塊內(nèi)某個(gè)包內(nèi)的 public 成員可以被其他模塊訪問,也就是開放了可讀性。如果一個(gè)模塊代碼中直接訪問了一個(gè)其他模塊沒有 exports 的成員,那么代碼不通過編譯。 exports 語句可以和 to 搭配,代表對(duì)指定模塊開放這些成員。

  3. opens 語句,和 exports 類似,但是它開放的是訪問性。也就是說,允許通過反射訪問模塊中的類。這個(gè)語句也可以和 to 搭配。 當(dāng)模塊被定義為 open module 時(shí),模塊內(nèi)的所有成員都將開放訪問,并且不允許在模塊中重新定義 opens。

  4. uses 語句,用于使用服務(wù)。服務(wù)通常是抽象類,比如說 java.sql.Driver。服務(wù)類所在的模塊必須使用 requires 進(jìn)行依賴。

  5. provides ... with ... 語句,它代表提供服務(wù)的實(shí)現(xiàn)類。

下面是 opens 和 exports 搭配使用的情況:

opens 和 exports 搭配使用的情況

模塊的字節(jié)碼表示

和普通的類一樣,模塊也是使用 ClassWriter 寫入的,但是寫入類信息的時(shí)候和普通的類不一樣:它要求類名稱是 module-info,僅帶有 ACC_MODULE 訪問標(biāo)志,并且沒有超類和簽名

接下來就是寫入模塊信息,這里用到了 visitModule 方法。如果模塊是 open 的,那么訪問標(biāo)志要寫為 ACC_OPEN,否則寫為0。最后一個(gè)參數(shù)是模塊的版本,可以為 null。

模塊中有三種定義信息的模式:

  • 顯式定義,也就是在文件中顯式寫出

  • 隱式定義,由模塊的依賴關(guān)系自行推斷而出

  • 既不是顯式定義也不是隱式定義,由編譯器編譯時(shí)決定添加

如果訪問標(biāo)志含有 ACC_MANDATED,則說明這個(gè)信息是被隱式定義的;如果訪問標(biāo)志含有 ACC_SYNTHETIC,則這個(gè)模塊信息既不是顯式定義也不是隱式定義。所有使用訪問標(biāo)志的模塊信息都可以使用這兩個(gè)標(biāo)志,下文將不再重復(fù)出現(xiàn)。

接下來就是填充模塊的信息,這些信息與 ModuleVisitor 類中的方法一一對(duì)應(yīng)。

requires 語句對(duì)應(yīng) visitRequire 方法,第一個(gè)參數(shù)是依賴模塊的名稱,最后一個(gè)參數(shù)是依賴模塊的版本。第二個(gè)參數(shù)訪問標(biāo)志可以使用 ACC_TRANSITIVE ACC_STATIC_PHASE,分別代表了 transitive static。

由于所有的模塊都隱式定義了 requires java.base,所以所有模塊都必須像下面一樣寫入:

exports opens 語句分別使用了 visitExport visitOpen 方法,參數(shù)分別是全限定包名、訪問標(biāo)志和指定模塊列表,最后一個(gè)參數(shù)可以為 null,代表向所有模塊開放。

uses 語句使用 visitUse 方法寫入,它唯一的參數(shù)代表服務(wù)類全限定名。

provides ... with ... 語句使用 visitProvide 方法,其中第一個(gè)參數(shù)代表服務(wù)類的全限定名,第二個(gè)則是實(shí)現(xiàn)類的列表。

現(xiàn)在,ModuleVisitor 類中還有兩個(gè)方法我們沒有說到:visitPackage visitMainClass。這兩個(gè)方法的實(shí)際作用不大,所以不講解它的用法。

到這里模塊的知識(shí)就結(jié)束了,下一篇專欄將講述注解的使用。

若無特殊說明,所有字節(jié)碼均以 Java 17 為標(biāo)準(zhǔn)。

參考資料:

  • The Java Language Specification (Java SE 17 Edition)

    https://docs.oracle.com/javase/specs/jls/se17/html/index.html

  • The Java Virtual Machine Specification (Java SE 17 Edition)

    https://docs.oracle.com/javase/specs/jvms/se17/html/index.html

  • ASM 9.4 Javadoc

    https://asm.ow2.io/javadoc/index.html

如果對(duì)文章內(nèi)容有問題或文章有錯(cuò)誤可以評(píng)論區(qū)或私信指出。

Java ASM詳解:模塊的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
陇南市| 乌鲁木齐县| 清远市| 沙坪坝区| 乌鲁木齐市| 武胜县| 靖西县| 呈贡县| 元谋县| 汉中市| 新安县| 庄河市| 鱼台县| 吴江市| 华安县| 兴和县| 河津市| 鄯善县| 巧家县| 合川市| 曲阳县| 青神县| 阿城市| 醴陵市| 宁化县| 京山县| 社旗县| 宜良县| 齐河县| 奉化市| 高唐县| 兴国县| 黔东| 青冈县| 玛曲县| 建昌县| 来安县| 卢龙县| 咸丰县| 普陀区| 保定市|