五月天青色头像情侣网名,国产亚洲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ó)家法律
会昌县| 肃宁县| 法库县| 夏津县| 安阳县| 廊坊市| 卓资县| 宜兰县| 济南市| 怀柔区| 龙泉市| 卫辉市| 天台县| 手游| 登封市| 平阳县| 昌吉市| 湖口县| 麻栗坡县| 本溪市| 满洲里市| 孟连| 太康县| 嘉祥县| 项城市| 维西| 盐源县| 元谋县| 惠东县| 景洪市| 元阳县| 铜鼓县| 宁强县| 南川市| 泾源县| 永川市| 大安市| 上杭县| 扎鲁特旗| 彩票| 射阳县|