日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

java 0000 0001 0002 000a 000b_Java代码编译后的class文件

發(fā)布時間:2025/3/21 java 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java 0000 0001 0002 000a 000b_Java代码编译后的class文件 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

還是熟悉的味道,還是最簡單的代碼。

// Hello.java

public class Hello {

public static void main(String[] args) {

System.out.println("Hello World!");

}

}

使用javac編譯 .java 代碼,得到同名的 .class文件,然后使用 java 命令,執(zhí)行類名就可以運行了。

$ javac Hello.java

$ java Hello

Hello World!

編譯后的class文件,以十六進(jìn)制格式顯示,長這個樣子:

cafe babe 0000 0034 001d 0a00 0600 0f09

0010 0011 0800 120a 0013 0014 0700 1507

0016 0100 063c 696e 6974 3e01 0003 2829

5601 0004 436f 6465 0100 0f4c 696e 654e

756d 6265 7254 6162 6c65 0100 046d 6169

6e01 0016 285b 4c6a 6176 612f 6c61 6e67

2f53 7472 696e 673b 2956 0100 0a53 6f75

7263 6546 696c 6501 000a 4865 6c6c 6f2e

6a61 7661 0c00 0700 0807 0017 0c00 1800

1901 000c 4865 6c6c 6f20 576f 726c 6421

0700 1a0c 001b 001c 0100 0548 656c 6c6f

0100 106a 6176 612f 6c61 6e67 2f4f 626a

6563 7401 0010 6a61 7661 2f6c 616e 672f

5379 7374 656d 0100 036f 7574 0100 154c

6a61 7661 2f69 6f2f 5072 696e 7453 7472

6561 6d3b 0100 136a 6176 612f 696f 2f50

7269 6e74 5374 7265 616d 0100 0770 7269

6e74 6c6e 0100 1528 4c6a 6176 612f 6c61

6e67 2f53 7472 696e 673b 2956 0021 0005

0006 0000 0000 0002 0001 0007 0008 0001

0009 0000 001d 0001 0001 0000 0005 2ab7

0001 b100 0000 0100 0a00 0000 0600 0100

0000 0100 0900 0b00 0c00 0100 0900 0000

2500 0200 0100 0000 09b2 0002 1203 b600

04b1 0000 0001 000a 0000 000a 0002 0000

0003 0008 0004 0001 000d 0000 0002 000e

這就是可供Java虛擬機(jī)執(zhí)行的字節(jié)碼文件,也是Java之所以能夠?qū)崿F(xiàn),一次編譯多次運行的根本原因。

把代碼編譯成一個中間狀態(tài)的字節(jié)碼,而不是直接運行在操作系統(tǒng)上的機(jī)器碼,使得跨系統(tǒng)的工作就完全交給Java虛擬機(jī)了。這樣一來,就可以大大減少開發(fā)人員的適配工作量,從而提高開發(fā)效率,這就是所謂的平臺無關(guān)性。

采用Java虛擬機(jī)的架構(gòu)設(shè)計,為語言擴(kuò)展留下了空間,相當(dāng)于給代碼編譯和操作系統(tǒng)做了一個中間件,只要將代碼編譯成字節(jié)碼文件,就都可以運行在Java虛擬機(jī)上,這也是為什么會有Scala 、Kotlin、Groovy等多種語言都可以與Java混合編碼的原因,這就是所謂的語言無關(guān)性。

既然我們看到了這個字節(jié)碼文件,那就得好好解讀一下了。其實只要是代碼編譯的文件,都是有約定的規(guī)范格式的,字節(jié)碼也是一樣的。

1. class文件結(jié)構(gòu)

類型

名稱

說明

備注或示例對照

u4

magic

魔數(shù),識別class文件

cafe babe

u2

minor_version

副版本號

0000

u2

major_version

主版本號

0034

u2

constant_pool_count

常量池計數(shù)器

001d,十進(jìn)制值為29

cp_info

constant_pool

常量池

常量個數(shù)為constant_pool_count-1,

示例即為28個常量

u2

access_flags

訪問標(biāo)志

0021

u2

this_class

類索引

0005

u2

super_class

父類索引

0006

u2

interfaces_count

接口計數(shù)器

0000

u2

interfaces

接口索引集合

u2

fields_count

字段個數(shù)

0000

field_info

fields

字段集合

u2

methods_count

方法計數(shù)器

0002

method_info

methods

方法集合

u2

attributes_count

附加屬性計數(shù)器

0001

attribute_info

attributes

附加屬性集合

000d 0000 0002 000e

class文件偽結(jié)構(gòu)中只有兩種數(shù)據(jù)類型:無符號數(shù)和表。

無符號數(shù)屬于基本的數(shù)據(jù)類型,以u1、u2、u4和u8來分表代表1個字節(jié)、2個字節(jié)、4個字節(jié)和8個字節(jié)的無符號數(shù),無符號數(shù)可以用來描述數(shù)字、索引引用、數(shù)量值或者按照UTF-8編碼構(gòu)成字符串值。

表是由多個無符號數(shù)或者其他表作為數(shù)據(jù)項構(gòu)成的復(fù)合數(shù)據(jù)類型,所有表都習(xí)慣地以"_info"結(jié)尾。表用于描述有層次關(guān)系的復(fù)合結(jié)構(gòu)的數(shù)據(jù),而整個class文件本質(zhì)上就是一張表。

2. 常量類型

類型

標(biāo)志

描述

CONSTANT_Utf8_info

1

UTF-8編碼的字符串

CONSTANT_Integer_info

3

整形字面量

CONSTANT_Float_info

4

浮點型字面量

CONSTANT_Long_info

5

長整型字面量

CONSTANT_Double_info

6

雙精度浮點型字面量

CONSTANT_Class_info

7

類或接口的符號引用

CONSTANT_String_info

8

字符串類型字面量

CONSTANT_Fieldref_info

9

字段的符號引用

CONSTANT_Methodref_info

10

類中方法的符號引用

CONSTANT_InterfaceMethodref_info

11

接口中方法的符號引用

CONSTANT_NameAndType_info

12

字段或方法的符號引用

CONSTANT_MethodHandle_info

15

表示方法句柄

CONSTANT_MothodType_info

16

標(biāo)識方法類型

CONSTANT_InvokeDynamic_info

18

表示一個動態(tài)方法調(diào)用點

3. 常量結(jié)構(gòu)

常量

項目

類型

描述

CONSTANT_Utf8_info

tag

u1

值為1

length

u2

utf-8編碼的字符串占用的字節(jié)數(shù)

bytes

u1

長度為length的utf-8編碼的字符串

CONSTANT_Integer_info

tag

u1

值為3

bytes

u4

按照高位在前存儲的int值

CONSTANT_Float_info

tag

u1

值為4

bytes

u4

按照高位在前存儲的floatt值

CONSTANT_Long_info

tag

u1

值為5

bytes

u8

按照高位在前存儲的long值

CONSTANT_Double_info

tag

u1

值為6

bytes

u8

按照高位在前存儲double值

CONSTANT_Class_info

tag

u1

值為7

index

u2

指向全限定名常量的索引

CONSTANT_String_info

tag

u1

值為8

index

u2

指向字符串字面量的索引

CONSTANT_Fieldref_info

tag

u1

值為9

index

u2

指向聲明字段的類或者接口描述符CONSTANT_Class_info的索引項

index

u2

指向字段描述符CONSTANT_NameAndType_info的索引項

CONSTANT_Methodref_info

tag

u1

值為10

index

u2

指向聲明方法的類描述符CONSTANT_Class_info的索引項

index

u2

指向名稱及類型描述符CONSTANT_NameAndType_info的索引項

CONSTANT_InterfaceMethodref_info

tag

u1

值為11

index

u2

指向聲明方法的接口描述符CONSTANT_Class_info的索引項

index

u2

指向名稱及類型描述符CONSTANT_NameAndType_info的索引項

CONSTANT_NameAndType_info

tag

u1

值為12

index

u2

指向該字段或方法名稱常量項的索引

index

u2

指向該字段或方法描述符常量項的索引

CONSTANT_MethodHandle_info

tag

u1

值為15

reference_kind

u1

值必須是1-9,它決定了方法句柄的類型,方法句柄類型的值表示方法句柄的字節(jié)碼行為

reference_index

u2

值必須是對常量池的有效索引

CONSTANT_MothodType_info

tag

u1

值為16

descriptor_index

u2

值必須是對常量池的有效索引,常量池在該索引處的項必須是CONSTANT_Utf8_info結(jié)構(gòu),表示方法的描述符

CONSTANT_InvokeDynamic_info

tag

u1

值為18

bootstrap_method_attr_index

u2

值必須是對當(dāng)前Class文件中引導(dǎo)方法表示的bootstrap_methods[]數(shù)組的有效索引

name_and_type_index

u2

值必須是對當(dāng)前常量池的有效索引,常量池在該索引處的項必須是CONSTANT_NameAndType_info結(jié)構(gòu),表示方法名和方法描述符

人工解讀示例字節(jié)碼中的常量池部分

0a 0013 0014 0700 1507

0016 0100 063c 696e 6974 3e01 0003 2829

5601 0004 436f 6465 0100 0f4c 696e 654e

756d 6265 7254 6162 6c65 0100 046d 6169

6e01 0016 285b 4c6a 6176 612f 6c61 6e67

2f53 7472 696e 673b 2956 0100 0a53 6f75

7263 6546 696c 6501 000a 4865 6c6c 6f2e

6a61 7661 0c00 0700 0807 0017 0c00 1800

1901 000c 4865 6c6c 6f20 576f 726c 6421

0700 1a0c 001b 001c 0100 0548 656c 6c6f

0100 106a 6176 612f 6c61 6e67 2f4f 626a

6563 7401 0010 6a61 7661 2f6c 616e 672f

5379 7374 656d 0100 036f 7574 0100 154c

6a61 7661 2f69 6f2f 5072 696e 7453 7472

6561 6d3b 0100 136a 6176 612f 696f 2f50

7269 6e74 5374 7265 616d 0100 0770 7269

6e74 6c6e 0100 1528 4c6a 6176 612f 6c61

6e67 2f53 7472 696e 673b 2956

index

十六進(jìn)制碼

長度

類型或備注

1

0a

1

CONSTANT_Methodref_info

0006

2

#6

000f

2

#15

2

09

1

CONSTANT_Fieldref_info

0010

2

#10

0011

2

#11

3

08

1

CONSTANT_String_info

0012

2

#18

4

0a

1

CONSTANT_Methodref_info

0013

2

#19

0014

2

#20

5

07

1

CONSTANT_Class_info

0015

2

#21

6

07

1

CONSTANT_Class_info

0016

2

#22

7

01

1

CONSTANT_Utf8_info

0006

2

length=6

3c 696e 6974 3e

6

8

01

1

CONSTANT_Utf8_info

0003

2

length=3

2829 56

3

()V

9

01

1

CONSTANT_Utf8_info

0004

2

length=4

436f 6465

4

Code

10

01

1

CONSTANT_Utf8_info

000f

2

length=15

4c 696e 654e 756d 6265 7254 6162 6c65

15

LineNumberTable

11

01

1

CONSTANT_Utf8_info

0004

2

6d 6169 6e

4

main

12

01

1

CONSTANT_Utf8_info

0016

2

285b 4c6a 6176 612f 6c61 6e672f53 7472 696e 673b 2956

22

([Ljava/lang/String;)V

13

01

1

CONSTANT_Utf8_info

000a

2

53 6f757263 6546 696c 65

10

SourceFile

14

01

1

CONSTANT_Utf8_info

000a

2

4865 6c6c 6f2e 6a61 7661

10

Hello.java

15

0c

1

CONSTANT_NameAndType_info

0007

2

0008

2

16

07

1

CONSTANT_Class_info

0017

2

17

0c

1

CONSTANT_NameAndType_info

0018

2

0019

2

18

01

1

CONSTANT_Utf8_info

000c

2

4865 6c6c 6f20 576f 726c 6421

12

Hello World!

19

07

1

CONSTANT_Class_info

001a

2

20

0c

1

CONSTANT_NameAndType_info

001b

2

001c

2

21

01

1

CONSTANT_Utf8_info

0005

2

48 656c 6c6f

5

Hello

22

01

1

CONSTANT_Utf8_info

0010

2

6a 6176 612f 6c61 6e67 2f4f 626a 6563 74

16

java/lang/Object

23

01

1

CONSTANT_Utf8_info

0010

2

6a61 7661 2f6c 616e 672f 5379 7374 656d

16

java/lang/System

24

01

1

CONSTANT_Utf8_info

0003

2

6f 7574

3

out

25

01

1

CONSTANT_Utf8_info

0015

2

4c 6a61 7661 2f69 6f2f 5072 696e 7453 74726561 6d3b

21

Ljava/io/PrintStream;

26

01

1

CONSTANT_Utf8_info

0013

2

6a 6176 612f 696f 2f50 7269 6e74 5374 7265 616d

19

java/io/PrintStream

27

01

1

CONSTANT_Utf8_info

0007

2

70 7269 6e74 6c6e

7

println

28

01

1

CONSTANT_Utf8_info

0015

2

28 4c6a 6176 612f 6c61 6e67 2f53 7472 696e 673b 2956

21

(Ljava/lang/String;)V

4. 類訪問標(biāo)志

標(biāo)志名稱

標(biāo)志值

含義

ACC_PUBLIC

0x0001

是否為public類型

ACC_FINAL

0x0010

是否被聲明為final,只有類可以設(shè)置

ACC_SUPER

0x0020

是否允許使用invokespecial字節(jié)碼指令的新語義,JDK1.0.2之后編譯出來的類的這個標(biāo)志默認(rèn)為真

ACC_INTERFACE

0x0200

標(biāo)志這是一個接口

ACC_ABSTRACT

0x0400

是否為abstract類型,對于接口或者抽象類來說,此標(biāo)志值為真,其他類型為假

ACC_SYNTHETIC

0x1000

標(biāo)志這個類并非由用戶代碼產(chǎn)生

ACC_ANNOTATION

0x2000

標(biāo)志這是一個注解

ACC_ENUM

0x4000

標(biāo)志這是一個枚舉

5. 方法表結(jié)構(gòu)

類型

名稱

數(shù)量

u2

access_flags

1

u2

name_index

1

u2

descriptor_index

1

u2

attributes_count

1

attribute_info

attributes

attributes_count

6. 方法訪問標(biāo)志

標(biāo)志名稱

標(biāo)志值

含義

ACC_PUBLIC

0x0001

方法是否為public

ACC_PRIVATE

0x0002

方法是否為private

ACC_PROTECTED

0x0004

方法是否為protected

ACC_STATIC

0x0008

方法是否為static

ACC_FINAL

0x0010

方法是否為final

ACC_SYHCHRONRIZED

0x0020

方法是否為synchronized

ACC_BRIDGE

0x0040

方法是否是有編譯器產(chǎn)生的方法

ACC_VARARGS

0x0080

方法是否接受參數(shù)

ACC_NATIVE

0x0100

方法是否為native

ACC_ABSTRACT

0x0400

方法是否為abstract

ACC_STRICTFP

0x0800

方法是否為strictfp

ACC_SYNTHETIC

0x1000

方法是否是有編譯器自動產(chǎn)生的

7. 通用屬性結(jié)構(gòu)表

類型

名稱

數(shù)量

u2

attribute_name_index

1

u4

attribute_length

1

u1

info

attribute_length

人工解讀示例字節(jié)碼中的方法部分

0002 0001 0007 0008 0001

0009 0000 001d 0001 0001 0000 0005 2ab7

0001 b100 0000 0100 0a00 0000 0600 0100

0000 0100 0900 0b00 0c00 0100 0900 0000

2500 0200 0100 0000 09b2 0002 1203 b600

04b1 0000 0001 000a 0000 000a 0002 0000

0003 0008 0004

十六進(jìn)制碼

類型或備注

0002

方法個數(shù)為2

第一個方法

0001

方法標(biāo)志為public

0007

方法名索引為7,

0008

方法描述符索引為8,()V

0001

attribute個數(shù)為1

第一個屬性

0009

屬性索引為9, Code

0000 001d

屬性值長度為29

0001 0001 0000 0005 2ab7 0001 b100 0000 0100 0a00 0000 0600 0100 0000 01

29個字節(jié)

第二個方法

00 09

方法標(biāo)志為public,static

00 0b

方法名索引為11,main

00 0c

方法描述符索引為12,([Ljava/lang/String;)V

00 01

attribute個數(shù)為1

第一個屬性

00 09

屬性索引為9, Code

00 0000 25

屬性值長度為37

00 0200 0100 0000 09b2 0002 1203 b600 04b1 0000 0001 000a 0000 000a 0002 0000 0003 0008 0004

37個字節(jié)

屬性類型比較多,字段、接口和方法中都存在,但是都可以按照通用結(jié)構(gòu)進(jìn)行字節(jié)拆分。各個屬性有自己的表結(jié)構(gòu),不做逐一列舉,只列出常用的Code結(jié)構(gòu)做栗子。

8. Code屬性結(jié)構(gòu)表

類型

名稱

數(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

逐字節(jié)解讀雖然繁瑣,但是能加深對字節(jié)碼的結(jié)構(gòu)的理解。不過,在掌握了結(jié)構(gòu)原理之后,使用工具才是最實在的,畢竟人工解讀的效率太低了。

$ javap -verbose Hello.class

Classfile /Users/cage/Study/java_cmd/Hello.class

Last modified 2020-3-15; size 416 bytes

MD5 checksum e2e1c1e330c7df4592041d815080126b

Compiled from "Hello.java"

public class Hello

minor version: 0

major version: 52

flags: ACC_PUBLIC, ACC_SUPER

Constant pool:

#1 = Methodref #6.#15 // java/lang/Object."":()V

#2 = Fieldref #16.#17 // java/lang/System.out:Ljava/io/PrintStream;

#3 = String #18 // Hello World!

#4 = Methodref #19.#20 // java/io/PrintStream.println:(Ljava/lang/String;)V

#5 = Class #21 // Hello

#6 = Class #22 // java/lang/Object

#7 = Utf8

#8 = Utf8 ()V

#9 = Utf8 Code

#10 = Utf8 LineNumberTable

#11 = Utf8 main

#12 = Utf8 ([Ljava/lang/String;)V

#13 = Utf8 SourceFile

#14 = Utf8 Hello.java

#15 = NameAndType #7:#8 // "":()V

#16 = Class #23 // java/lang/System

#17 = NameAndType #24:#25 // out:Ljava/io/PrintStream;

#18 = Utf8 Hello World!

#19 = Class #26 // java/io/PrintStream

#20 = NameAndType #27:#28 // println:(Ljava/lang/String;)V

#21 = Utf8 Hello

#22 = Utf8 java/lang/Object

#23 = Utf8 java/lang/System

#24 = Utf8 out

#25 = Utf8 Ljava/io/PrintStream;

#26 = Utf8 java/io/PrintStream

#27 = Utf8 println

#28 = Utf8 (Ljava/lang/String;)V

{

public Hello();

descriptor: ()V

flags: ACC_PUBLIC

Code:

stack=1, locals=1, args_size=1

0: aload_0

1: invokespecial #1 // Method java/lang/Object."":()V

4: return

LineNumberTable:

line 1: 0

public static void main(java.lang.String[]);

descriptor: ([Ljava/lang/String;)V

flags: ACC_PUBLIC, ACC_STATIC

Code:

stack=2, locals=1, args_size=1

0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;

3: ldc #3 // String Hello World!

5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V

8: return

LineNumberTable:

line 3: 0

line 4: 8

}

SourceFile: "Hello.java"

有興趣的同學(xué),平時可以經(jīng)常看看字節(jié)碼文件及其結(jié)構(gòu),看都用到了哪些字節(jié)碼指令,這樣對理解Java代碼的執(zhí)行會更有好處。

總結(jié)

以上是生活随笔為你收集整理的java 0000 0001 0002 000a 000b_Java代码编译后的class文件的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。