歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Java Class文件格式解析

Java Class文件格式解析

日期:2017/3/1 9:19:44   编辑:Linux編程

一、Java Class文件是什麼

Java語言是跨平台的,所謂一次編寫,到處運行。之所以是跨平台的,就是Java定義了一套與操作系統,硬件無關的字節碼格式,這個字節碼就是用Java class文件來表示的,Java class文件內部定義了虛擬機可以識別的字節碼格式,這個格式是平台無關性的,在Linux系統或者在Windows系統上都是一致的。這個就好比html文件,我們定義好規范,這個系統只要去按照規范顯示出來裡面的內容就好了。好比html就是class文件,浏覽器就是虛擬機一樣,通過浏覽器去執行html的渲染過程,我們無論是用手機,Windows系統,蘋果系統上網,顯示出來的內容都是一樣。 Java虛擬機可以從class文件中加載預定義的字節碼,也可以從網絡,數據庫,消息文件中加載字節碼。

二、Java Class文件的格式

1.多個字節的數據采用大端存儲

2.class文件采用定義u1、u2、u4來表示無符號的1、2、4字節數據。

簡要解釋一下:

U4 代表由無符號四個字節組成

u4 magic :是一個固定的數值,java虛擬機裡面稱為魔數 ,主要是用來標識是否為java虛擬機所支持的文件結構,目前是0xCAFEBABE

u2 minor_version; u2 major_version; 代表次版本號和主版本號

u2 constant_pool_count; cp_info constant_pool[constant_pool_count-1]; 這裡面代表常量池個數以及常量池信息

u2 access_flags : 代表class訪問標記,例如:public protected

u2 this_class : 代表這個類的名稱 例如 java.lang.Object

u2 super_class : 代表父類名稱

u2 interfaces_count; u2 interfaces[interfaces_count]; 實現的接口格式以及接口類名

u2 fields_count; field_info fields[fields_count]; 字段個數以及字段信息

u2 methods_count; method_info methods[methods_count]; 方法個數以及方法信息

u2 attributes_count; attribute_info attributes[attributes_count]; java class文件內部屬性信息,和java語言定義的屬性沒有關系,純粹就是給java虛擬機用的

class文件實例

/*
* Copyright (c) 2015 Javaranger.com. All Rights Reserved.
*/
package com.javaranger.test;

/**
* @author tao.wang Date: 16/1/2 Time: 下午12:29
* @version $Id$
*/
public class ClassTest {
public int id = 100;
private String name = "javaranger";

public void test() {
int a = 1;
int b = 2;
int c = a + b;
String str = name + ".com";
System.out.println(str);
}

}

javap -v ClassTest.class

lassfile /Users/ranger/git/transformer/src/main/java/com/javaranger/test/ClassTest.class
Last modified 2016-1-2; size 713 bytes
MD5 checksum 67738e1dedfacaa7d62444f45d8cc716
Compiled from "ClassTest.java"
public class com.javaranger.test.ClassTest
SourceFile: "ClassTest.java"
minor version: 0
major version: 51
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #13.#25 // java/lang/Object."":()V
#2 = Fieldref #12.#26 // com/javaranger/test/ClassTest.id:I
#3 = String #27 // javaranger
#4 = Fieldref #12.#28 // com/javaranger/test/ClassTest.name:Ljava/lang/String;
#5 = Class #29 // java/lang/StringBuilder
#6 = Methodref #5.#25 // java/lang/StringBuilder."":()V
#7 = Methodref #5.#30 // java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
#8 = String #31 // .com
#9 = Methodref #5.#32 // java/lang/StringBuilder.toString:()Ljava/lang/String;
#10 = Fieldref #33.#34 // java/lang/System.out:Ljava/io/PrintStream;
#11 = Methodref #35.#36 // java/io/PrintStream.println:(Ljava/lang/String;)V
#12 = Class #37 // com/javaranger/test/ClassTest
#13 = Class #38 // java/lang/Object
#14 = Utf8 id
#15 = Utf8 I
#16 = Utf8 name
#17 = Utf8 Ljava/lang/String;
#18 = Utf8
#19 = Utf8 ()V
#20 = Utf8 Code
#21 = Utf8 LineNumberTable
#22 = Utf8 test
#23 = Utf8 SourceFile
#24 = Utf8 ClassTest.java
#25 = NameAndType #18:#19 // "":()V
#26 = NameAndType #14:#15 // id:I
#27 = Utf8 javaranger
#28 = NameAndType #16:#17 // name:Ljava/lang/String;
#29 = Utf8 java/lang/StringBuilder
#30 = NameAndType #39:#40 // append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
#31 = Utf8 .com
#32 = NameAndType #41:#42 // toString:()Ljava/lang/String;
#33 = Class #43 // java/lang/System
#34 = NameAndType #44:#45 // out:Ljava/io/PrintStream;
#35 = Class #46 // java/io/PrintStream
#36 = NameAndType #47:#48 // println:(Ljava/lang/String;)V
#37 = Utf8 com/javaranger/test/ClassTest
#38 = Utf8 java/lang/Object
#39 = Utf8 append
#40 = Utf8 (Ljava/lang/String;)Ljava/lang/StringBuilder;
#41 = Utf8 toString
#42 = Utf8 ()Ljava/lang/String;
#43 = Utf8 java/lang/System
#44 = Utf8 out
#45 = Utf8 Ljava/io/PrintStream;
#46 = Utf8 java/io/PrintStream
#47 = Utf8 println
#48 = Utf8 (Ljava/lang/String;)V
{
public int id;
flags: ACC_PUBLIC

public com.javaranger.test.ClassTest();
flags: ACC_PUBLIC
Code:
stack=2, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."":()V
4: aload_0
5: bipush 100
7: putfield #2 // Field id:I
10: aload_0
11: ldc #3 // String javaranger
13: putfield #4 // Field name:Ljava/lang/String;
16: return
LineNumberTable:
line 10: 0
line 11: 4
line 12: 10

public void test();
flags: ACC_PUBLIC
Code:
stack=2, locals=5, args_size=1
0: iconst_1
1: istore_1
2: iconst_2
3: istore_2
4: iload_1
5: iload_2
6: iadd
7: istore_3
8: new #5 // class java/lang/StringBuilder
11: dup
12: invokespecial #6 // Method java/lang/StringBuilder."":()V
15: aload_0
16: getfield #4 // Field name:Ljava/lang/String;
19: invokevirtual #7 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
22: ldc #8 // String .com
24: invokevirtual #7 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
27: invokevirtual #9 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
30: astore 4
32: getstatic #10 // Field java/lang/System.out:Ljava/io/PrintStream;
35: aload 4
37: invokevirtual #11 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
40: return
LineNumberTable:
line 15: 0
line 16: 2
line 17: 4
line 18: 8
line 19: 32
line 20: 40
}

cafe babe 0000 0033 0031 0a00 0d00 1909
000c 001a 0800 1b09 000c 001c 0700 1d0a
0005 0019 0a00 0500 1e08 001f 0a00 0500
2009 0021 0022 0a00 2300 2407 0025 0700
2601 0002 6964 0100 0149 0100 046e 616d
6501 0012 4c6a 6176 612f 6c61 6e67 2f53
7472 696e 673b 0100 063c 696e 6974 3e01
0003 2829 5601 0004 436f 6465 0100 0f4c
696e 654e 756d 6265 7254 6162 6c65 0100
0474 6573 7401 000a 536f 7572 6365 4669
6c65 0100 0e43 6c61 7373 5465 7374 2e6a
6176 610c 0012 0013 0c00 0e00 0f01 000a
6a61 7661 7261 6e67 6572 0c00 1000 1101
0017 6a61 7661 2f6c 616e 672f 5374 7269
6e67 4275 696c 6465 720c 0027 0028 0100
042e 636f 6d0c 0029 002a 0700 2b0c 002c
002d 0700 2e0c 002f 0030 0100 1d63 6f6d
2f6a 6176 6172 616e 6765 722f 7465 7374
2f43 6c61 7373 5465 7374 0100 106a 6176
612f 6c61 6e67 2f4f 626a 6563 7401 0006
6170 7065 6e64 0100 2d28 4c6a 6176 612f
6c61 6e67 2f53 7472 696e 673b 294c 6a61
7661 2f6c 616e 672f 5374 7269 6e67 4275
696c 6465 723b 0100 0874 6f53 7472 696e
6701 0014 2829 4c6a 6176 612f 6c61 6e67
2f53 7472 696e 673b 0100 106a 6176 612f
6c61 6e67 2f53 7973 7465 6d01 0003 6f75
7401 0015 4c6a 6176 612f 696f 2f50 7269
6e74 5374 7265 616d 3b01 0013 6a61 7661
2f69 6f2f 5072 696e 7453 7472 6561 6d01
0007 7072 696e 746c 6e01 0015 284c 6a61
7661 2f6c 616e 672f 5374 7269 6e67 3b29
5600 2100 0c00 0d00 0000 0200 0100 0e00
0f00 0000 0200 1000 1100 0000 0200 0100
1200 1300 0100 1400 0000 3100 0200 0100
0000 112a b700 012a 1064 b500 022a 1203
b500 04b1 0000 0001 0015 0000 000e 0003
0000 000a 0004 000b 000a 000c 0001 0016
0013 0001 0014 0000 0055 0002 0005 0000
0029 043c 053d 1b1c 603e bb00 0559 b700
062a b400 04b6 0007 1208 b600 07b6 0009
3a04 b200 0a19 04b6 000b b100 0000 0100
1500 0000 1a00 0600 0000 0f00 0200 1000
0400 1100 0800 1200 2000 1300 2800 1400
0100 1700 0000 0200 18

Copyright © Linux教程網 All Rights Reserved