国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

class文件中,常量池之后的相關(guān)數(shù)據(jù)解析!【class二進制文件分析】

這篇具有很好參考價值的文章主要介紹了class文件中,常量池之后的相關(guān)數(shù)據(jù)解析!【class二進制文件分析】。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

前言:前段時間讀《深入java虛擬機》介紹到class文件的時候,由于理論知識較多,人總感覺疲憊不堪,就泛泛閱讀了一下。在工作中使用起來知識點知道,但是總是需要查閱各種資料。今天有時間,繼續(xù)整理常量池后面的相關(guān)知識。

源碼

public class Sample {
    public String m1;
    public String m2;
    public Object [] arr;

    public static void main(String[] args) {
        Sample sample = new Sample();
        sample.m1="22";
        sample.arr=new Object[12];
        System.out.println(sample.m1);
    }
}

編譯之后的javap文件

  Last modified 2023-6-2; size 708 bytes
  MD5 checksum fc8bb4833223a10b68449d42080b1695
  Compiled from "Sample.java"
public class com.company.jvm.Sample
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Methodref          #6.#29         // java/lang/Object."<init>":()V
   #2 = Class              #30            // com/company/jvm/Sample
   #3 = Methodref          #2.#29         // com/company/jvm/Sample."<init>":()V
   #4 = String             #31            // 22
   #5 = Fieldref           #2.#32         // com/company/jvm/Sample.m1:Ljava/lang/String;
   #6 = Class              #33            // java/lang/Object
   #7 = Fieldref           #2.#34         // com/company/jvm/Sample.arr:[Ljava/lang/Object;
   #8 = Fieldref           #35.#36        // java/lang/System.out:Ljava/io/PrintStream;
   #9 = Methodref          #37.#38        // java/io/PrintStream.println:(Ljava/lang/String;)V
  #10 = Utf8               m1
  #11 = Utf8               Ljava/lang/String;
  #12 = Utf8               m2
  #13 = Utf8               arr
  #14 = Utf8               [Ljava/lang/Object;
  #15 = Utf8               <init>
  #16 = Utf8               ()V
  #17 = Utf8               Code
  #18 = Utf8               LineNumberTable
  #19 = Utf8               LocalVariableTable
  #20 = Utf8               this
  #21 = Utf8               Lcom/company/jvm/Sample;
  #22 = Utf8               main
  #23 = Utf8               ([Ljava/lang/String;)V
  #24 = Utf8               args
  #25 = Utf8               [Ljava/lang/String;
  #26 = Utf8               sample
  #27 = Utf8               SourceFile
  #28 = Utf8               Sample.java
  #29 = NameAndType        #15:#16        // "<init>":()V
  #30 = Utf8               com/company/jvm/Sample
  #31 = Utf8               22
  #32 = NameAndType        #10:#11        // m1:Ljava/lang/String;
  #33 = Utf8               java/lang/Object
  #34 = NameAndType        #13:#14        // arr:[Ljava/lang/Object;
  #35 = Class              #39            // java/lang/System
  #36 = NameAndType        #40:#41        // out:Ljava/io/PrintStream;
  #37 = Class              #42            // java/io/PrintStream
  #38 = NameAndType        #43:#44        // println:(Ljava/lang/String;)V
  #39 = Utf8               java/lang/System
  #40 = Utf8               out
  #41 = Utf8               Ljava/io/PrintStream;
  #42 = Utf8               java/io/PrintStream
  #43 = Utf8               println
  #44 = Utf8               (Ljava/lang/String;)V
{
  public java.lang.String m1;
    descriptor: Ljava/lang/String;
    flags: ACC_PUBLIC

  public java.lang.String m2;
    descriptor: Ljava/lang/String;
    flags: ACC_PUBLIC

  public java.lang.Object[] arr;
    descriptor: [Ljava/lang/Object;
    flags: ACC_PUBLIC

  public com.company.jvm.Sample();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: return
      LineNumberTable:
        line 3: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   Lcom/company/jvm/Sample;

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=2, args_size=1
         0: new           #2                  // class com/company/jvm/Sample
         3: dup
         4: invokespecial #3                  // Method "<init>":()V
         7: astore_1
         8: aload_1
         9: ldc           #4                  // String 22
        11: putfield      #5                  // Field m1:Ljava/lang/String;
        14: aload_1
        15: bipush        12
        17: anewarray     #6                  // class java/lang/Object
        20: putfield      #7                  // Field arr:[Ljava/lang/Object;
        23: getstatic     #8                  // Field java/lang/System.out:Ljava/io/PrintStream;
        26: aload_1
        27: getfield      #5                  // Field m1:Ljava/lang/String;
        30: invokevirtual #9                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        33: return
      LineNumberTable:
        line 9: 0
        line 10: 8
        line 11: 14
        line 12: 23
        line 13: 33
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      34     0  args   [Ljava/lang/String;
            8      26     1 sample   Lcom/company/jvm/Sample;
}
SourceFile: "Sample.java"

1、訪問標(biāo)志

class文件中,我們可以通過背或記也好,或者通過查閱對照表??梢詫⒊A砍刂械臄?shù)據(jù)整理出來。常量池的數(shù)據(jù),之后又是什么呢?緊接著的就是訪問標(biāo)志。

標(biāo)志名稱 標(biāo)志值 標(biāo)志意義
ACC_PUBLIC 0X0001 是否為public類型
ACC_FINAL 0X0010 是否被聲明為final,只有類可設(shè)置
ACC_SUPER 0x0020 在jdk1.0.2之后編譯出來的類的這個標(biāo)志都為真
ACC_INTERFACE 0x0200 標(biāo)識是一個接口
ACC_ABSTRACT 0x4000 是否為abstract類型,如為真,其他類型均為假,如INTERFACE
ACC_SYNTHETIC 0x1000 標(biāo)識這個類并非由用戶產(chǎn)生
ACC_ANNOTATION 0x2000 標(biāo)識這是一個注解
ACC_ENUM 0x4000 標(biāo)識這是一個枚舉
ACC_MODULE 0x8000 標(biāo)識這是一個模塊

這里先上一張二進制的圖:
class文件中,常量池之后的相關(guān)數(shù)據(jù)解析!【class二進制文件分析】

下面是常量池之后的class文件截取的部分:

00 21 

訪問標(biāo)志,占用空間:U2,這里占用了十六進制的4個位,則是0x0021。這里我啰嗦一下,一個字節(jié)為8個位,對應(yīng)到十六機制來說【兩個位】代表一個字節(jié)。eg:0xF標(biāo)識二進制的0000 1111,去除高位的0,就是1111。
在表格中我們說過,ACC_SUPER標(biāo)志在jdk1.0.2之后的版本其值都為真,則是0x0020,說明其訪問標(biāo)志ACC_PUBLIC為真!0x0001|0x0020=0x0021

2、類索引、父類索引、接口索引

訪問標(biāo)志結(jié)束之后,就來到了我們所聲明的類例,如下偽代碼

public class dog extend cat implement animal{

}
00 02 00 06 00 00

__類索引、父類索引、接口索引占用的內(nèi)存均為u2。

u2 索引 說明
00 02 #2 代表當(dāng)前類的索引,通過查找為com/company/jvm/Sample
00 08 #8 代表當(dāng)前父類索引,通過查找為Object
00 00 0 代表當(dāng)前文件沒有接口

字段表集合

通過字面意,就能得知這里將要介紹的是類或接口成員字段。

//這里寫個偽代碼
public final static int AGE=10;

1、字段表結(jié)構(gòu)

類型 名稱 數(shù)量 說明
u2 filed_count 1 字段數(shù)量
u2 access_flag 1 訪問標(biāo)志
u2 name_index 1 名稱索引
u2 descriptor_index 1 類型索引
u2 attribute_count 1 屬性計數(shù)器
u2 attributes attribute_count 屬性值集合

2、字段表的訪問標(biāo)識

標(biāo)志名稱 標(biāo)志值 含義
ACC_PUBLIC 0x0001 字段是否為公開
ACC_PRIVATE 0x0002 字段是否為私有
ACC_PROTECTED 0x0004 字段是否為保護
ACC_STATIC 0x0008 字段是否為靜態(tài)
ACC_FINAL 0x0010 字段是否為Final
ACC_VOLATILE 0x0040 字段是否在并發(fā)時可見
ACC_TRANSIENT 0x0080 字段是否序列化
ACC_SYNTHETIC 0x1000 字段是否由編譯器自己決定
ACC_ENUM 0x4000 字段是否為枚舉
00 03 00 01 00 0a 00 0b  00 00 00 01 00 0c 00 0b 00 00 00 01 00 0d 00 0e 00 00 
位值 說明
第一個成員字段
00 03 代表字段數(shù)量有3個
00 01 代表字段訪問標(biāo)志位public
00 0a 代表名稱索引為10 名稱為 m1
00 0b 代表descriptor的索引值為11 對象類型為Ljava/lang/String;【分號;全限定名】
00 00 代表沒有屬性數(shù)量
第二個成員字段
00 01 代表字段訪問標(biāo)志位為public
00 0c 代表字段名稱索引為12,名稱為m2
00 0b 代表類型的索引11,類型為 Ljava/lang/String;同上
00 00 代表沒有屬性
第三個成員字段
00 01 同上
00 0d 名稱索引為13,經(jīng)查找為arr
00 0e 類型索引為14,經(jīng)查找為 [Ljava/lang/Object;全限定名,其中“[”代表為數(shù)組
00 00 代表沒有屬性,數(shù)量為0

方法表集合

嘮嗑時間開始,寫到這里花了三個多小時。從排版到書寫上面確實有很大的提升。此時的我確實有點疲憊。仔細一想,沒啥子疲憊不疲憊的,路雖遠,但始終在路上,總會到達終點。突然想到書上說過這樣的一句:當(dāng)你在解決一個問題的時候,你會感到很疲憊,這時候千萬別放棄。因為大部分的人就此放棄了,而你還在路上行走。當(dāng)你解決之后,你又比別人強了不少!

寫到這里【字段表集合】之后,這里就會很輕松。這里再啰嗦一下,字段表分為:成員字段數(shù)量、字段名索引、字段類型索引、字段屬性數(shù)量、字段屬性集合。

1、方法表結(jié)構(gòu)

類型 名稱 數(shù)量 說明
method_count 方法數(shù)量
u2 access_flag 1 訪問標(biāo)志
u2 name_index 1 名稱索引
u2 descriptor_index 1 類型索引
u2 attributes_count 1 屬性數(shù)量
attributes_count attributes_[attributes_count] 1 屬性表

2、方法表的訪問標(biāo)識

標(biāo)志名稱 標(biāo)志值 含義
ACC_PUBLIC 0x0001 方法是否為公開
ACC_PRIVATE 0x0002 方法是否為私有
ACC_PROTECTED 0x0004 方法是否為保護
ACC_STATIC 0x0008 方法是否為靜態(tài)
ACC_FINAL 0x0010 方法是否為Final
ACC_SYNCHRONIZED 0x0020 方法是否在并發(fā)時可見
ACC_BRIDGE 0x0040 方法是不是由編譯器產(chǎn)生的橋接方法
ACC_VARCHAR 0x0080 方法是否接收不可定參數(shù)
ACC_NATIVE 0x0100 方法是否為Native
ACC_ABSTRACT 0x0400 方法是否為abstract
ACC_STRICT 0x0800 方法是否為strictfp【修飾在接口和類,對精確率類型較高且跨平臺的計算結(jié)果要求比較嚴格的清醒的話,建議使用該strictfp關(guān)鍵詞?!?/td>
ACC_SYNTHETIC 0x1000 方法是否由編譯器自動產(chǎn)生

code屬性表

類型 名稱 數(shù)量
u2 attribute_name_index 1
u4 attribute_length 1
u2 max_stack 1
u2 max_locals 1
u4 code_length 1
u1 code code_length
u2 exception_table_length 1
exception_info exception_table exception_table_length
u2 attributes_count 1
attribute_info attributes attributes_count

繼續(xù)上方法表的字節(jié)碼:

00 02 00 01 00 0f 00 10 00 01 00 11 00 00 00 2f 00 00 00 01 00 00 00 05 2a b7 00 01 b1 00 00

現(xiàn)在對照上面的說明,現(xiàn)在逐一說明:

對照 位碼 說明
methods_count 00 02 存在2個方法
acc_flags 00 01 訪問標(biāo)識 public
name_index 00 0f 方法名索引為15,經(jīng)查為< init >
descriptor_index 00 10 方法描述索引為16,經(jīng)常為()v
attributes_count 00 01 屬性只有一個
attributes_name_index 00 11 屬性名索引為17,經(jīng)查為code
attributes_length 00 00 00 2f 屬性值長度為47
max_stack 00 00 最大棧深為0
max_locals 00 01 需要分配1個變量槽,根據(jù)同時生存的最大局部變量數(shù)和類型計算
code_length 00 00 00 05 字節(jié)碼長度
code 2a 查看指令表為aload_0
code b7 同上~,invokespecial,調(diào)用超類構(gòu)造方法,實例初始化方法,私有方法
code 00 同上~,nop,什么都不做
code 01 同上~,acoust_null,將null推送至棧頂
code b1 同上~,return ,從當(dāng)前方法返回void
exception_table_lenght 00 00 當(dāng)前沒有發(fā)現(xiàn)異常信息
attributes_count 00 02 該方法的附加屬性共有2個
attribute_name_index 0012 屬性名索引為18,經(jīng)查為 LineNumberTable
attribute_length 00 00 00 06 屬性長度為6
line_number_table_length 00 01 字節(jié)碼行號共1行
star_pc 00 00 從字節(jié)碼第0行開始。此處說的行數(shù)是一種抽象的,指的是相對于方法體的偏移
line_number 00 03java行號為3
attribute_name_index 00 13 屬性名稱索引為19,經(jīng)查為 LocalVariableTable
attribute_length 00 00 00 0c 屬性長度為12
local_variable_table_length 00 01 局部變量表長度為1
star_pc 00 00 局部變量的生命周期開始的字節(jié)碼偏移量
length 00 05 往后偏移5個地址的長度,star_pc和length的配合使用就是局部變量在字節(jié)碼中的作用域范圍
name_index 00 14 名字索引為20,經(jīng)查為 this
descriptor_index 00 15 描述索引為21,經(jīng)查為Lcom/company/jvm/Sample;
index 00 00 這個局部變量在棧幀的局部變量表中變量槽的為之為0
acc_flag 00 09 public的標(biāo)志0x0001,static的標(biāo)志0x0008,0x0001
name_index 00 16 名字為索引22,經(jīng)查為 main
descriptor_index 00 17 描述的索引為23,經(jīng)查([Ljava/lang/String;)V
attributes_count 00 01 當(dāng)前方法的屬性長度為1
attribute_name_index 00 11 當(dāng)前屬性名稱索引值為17,經(jīng)查為Code
attribute_length 00 00 00 66 當(dāng)前屬性的長度為102
attribute_name_index 00 02 屬性名稱索引為2,經(jīng)查為com/company/jvm/Sample
max_stack 00 02 棧幀最大深度為2
max_local 00 02 最大局部變量槽數(shù)為2
code_lenght 00 00 00 22 字節(jié)碼長度為34
code bb 經(jīng)查字節(jié)碼指令,0xbb為new
code 00 Nop,什么事都不做
code 02 同上經(jīng)查,為將int型-1推送至棧頂
code 59 0x59,經(jīng)查為dump,賦值棧頂數(shù)值并壓入棧頂
code b7 0xb7,invokespecial,調(diào)用超類構(gòu)造方法,實例化初始方法,私有方法
code 00 Nop 不做任何事
code 03 0x03,將int的0推送至棧頂
code 0x27e 一直都這個位都是code值
exception_table_lenght 00 00 說明沒有任何異常信息
attributes_count 00 02 說明有兩條
同上面分析~ 同上面分析~ 同上面分析~

到最后8位為Source

標(biāo)識 位碼 說明
attribute_name_index 00 1b 名稱索引為27,經(jīng)查為SourceFile
attribute_length 00 00 00 02 對應(yīng)值為2
sourcefile_index 00 1c 對應(yīng)的文件索引值為28, 經(jīng)查為Sample.java

至此一個簡單的文件就翻譯完成了,對照著javap和字節(jié)碼整理之后,確實有一番收獲。但是還處于道可道非常道的過程,仍然需要透徹一些!明天繼續(xù)干~文章來源地址http://www.zghlxwxcb.cn/news/detail-469025.html

到了這里,關(guān)于class文件中,常量池之后的相關(guān)數(shù)據(jù)解析!【class二進制文件分析】的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • C#藍牙連接及傳輸數(shù)據(jù)的三種方式(藍牙傳輸文件、二進制數(shù)據(jù))

    C#藍牙連接及傳輸數(shù)據(jù)的三種方式(藍牙傳輸文件、二進制數(shù)據(jù))

    ? ? ? 先下載InTheHand.Net.Personal.dll并在C#中引用,這個需要在網(wǎng)上下載 ? ? ?先看界面 ? ? ? ? ? ?這種方式優(yōu)點是穩(wěn)定性較強,基本無錯誤,就是偶爾需要提前藍牙配對。 ? ? ? ?這種方式直接與藍牙設(shè)備進行配對的時候會報錯,請求的地址無效,這時候需要在被檢測的藍牙

    2024年02月11日
    瀏覽(31)
  • 深入理解前端字節(jié)二進制知識以及相關(guān)API

    深入理解前端字節(jié)二進制知識以及相關(guān)API

    當(dāng)前,前端對二進制數(shù)據(jù)有許多的API可以使用,這豐富了前端對文件數(shù)據(jù)的處理能力,有了這些能力,就能夠?qū)D片等文件的數(shù)據(jù)進行各種處理。 本文將著重介紹一些前端二進制數(shù)據(jù)處理相關(guān)的API知識,如Blob、File、FileReader、ArrayBuffer、TypeArray、DataView等等。 在介紹各種API之

    2024年02月03日
    瀏覽(22)
  • 在線解析二進制報文

    在線解析二進制報文

    智能設(shè)備應(yīng)用越來越普遍,深入到生活的各個方面,從智慧農(nóng)業(yè)到智能制造,從水利灌溉到電力傳輸,從工業(yè)生產(chǎn)到智能家居。智能設(shè)備應(yīng)用在各個領(lǐng)域,設(shè)備之間都是通過數(shù)據(jù)交換來達到信息共享和互相操作,交換的數(shù)據(jù)都遵守某個協(xié)議標(biāo)準,在測試時,調(diào)試時和排查問題

    2024年02月06日
    瀏覽(18)
  • 【Unity】二進制文件 數(shù)據(jù)持久化(修改版)【個人復(fù)習(xí)筆記/有不足之處歡迎斧正/侵刪】

    ???????? 變量的本質(zhì)都是二進制 ,在內(nèi)存中都以字節(jié)的形式存儲著,通過sizeof方法可以看到常用變量類型占用的字節(jié)空間長度( 1byte = 8bit,1bit(位)不是0就是1 ) ? ? ? ? 二進制文件讀寫的本質(zhì): 將各類型變量轉(zhuǎn)換為字節(jié)數(shù)組,將字節(jié)數(shù)組直接存儲到文件中 ,不僅可以節(jié)

    2024年04月17日
    瀏覽(25)
  • uniapp小程序(原生微信小程序也可以使用),獲取接口二進制流數(shù)據(jù)上傳文件到服務(wù)器

    需求:通過接口返回的二進制流數(shù)據(jù),這個流數(shù)據(jù)他是一個xlsx文檔,需要給到用戶一個文檔線上連接。 下面是具體代碼,注意只針對二進制的文件數(shù)據(jù),如果圖片上傳直接調(diào)用uploadFile就可以,并且兼容原生微信小程序。 ?

    2024年02月16日
    瀏覽(101)
  • 深入解析位運算算法:探索數(shù)字的二進制秘密

    位運算是計算機科學(xué)中的重要概念,用于在二進制數(shù)字層面進行各種操作。本文將深入介紹位運算的基本操作,以及它在判斷、計算和處理數(shù)字中的應(yīng)用,包括判斷2的冪次方、位圖法、位掩碼和尋找缺失數(shù)字等。 位操作是通過對數(shù)字的二進制表示進行操作,實現(xiàn)各種功能。

    2024年02月11日
    瀏覽(21)
  • 算法-回溯相關(guān)問題-生成所有n位長的二進制字符串 Java版

    生成所有n位長的二進制字符串。假設(shè)A[0…n-1]是一個大小為n的數(shù)組。

    2024年02月16日
    瀏覽(18)
  • Linux查看二進制文件

    Linux查看二進制文件

    hexdump 、 hd 、 od 、 xxd hexdump 、 hd 可以使用16進制、10進制、8進制、 ascii 碼的形式查看文件。 執(zhí)行 就會看到hd其實只是hexdump的一個軟鏈接。 使用 man hexdump ,可以查看 hexdump 的各種參數(shù)。 length and offset 參數(shù)后面可以跟后綴KiB(=1024)、MiB(=1024 1024),依此類推GiB、TiB、PiB、

    2024年02月08日
    瀏覽(21)
  • 【VSCode】查看二進制文件

    【VSCode】查看二進制文件

    1.安裝插件Hex Editor 2.打開二進制文件 3.執(zhí)行Hex Editor命令

    2024年02月13日
    瀏覽(23)
  • Python讀寫二進制文件

    Python 讀寫文件的二進制數(shù)據(jù)需要使用到struct模塊,進行C/C++與Python數(shù)據(jù)格式的轉(zhuǎn)換。 struct模塊中最常用的函數(shù)為pack和unpack,用法如下: 函數(shù) return explain pack(fmt,v1,v2…) string 按照給定的格式(fmt),把數(shù)據(jù)轉(zhuǎn)換成字符串(字節(jié)流),并將該字符串返回. pack_into(fmt,buffer,offset,v1,v2…) No

    2024年02月08日
    瀏覽(21)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包