1. 程式人生 > >Java Class檔案格式解析及例項

Java Class檔案格式解析及例項

JAVA無關性概述

Java語言從剛誕生開始曾提出一個非常著名的宣言:“一次編寫,到處執行(Write Once, Run Anywhere)”。Sun公司和其他虛擬機器公司釋出了許多可以執行在不同作業系統上的虛擬機器,這些虛擬機器都可以載入和執行同一種平臺無關的位元組碼,從而實現其宣言。

同時Java平臺還有另外一個無關性,語言無關性。實現語言無關性的的基礎仍然是虛擬機器和位元組碼儲存格式。虛擬機器並不關心Class檔案的來源語言,只要它符合Class檔案的結構就可以在Java虛擬機器中執行。

Class檔案結構

首先我們需要明確
1,多個位元組的資料採用大端儲存

2,class檔案採用定義u1、u2、u4來表示無符號的1、2、4位元組資料。

如下圖所示為Java 虛擬機器規範中描述的結構


其中,

1,Magic Number為4個位元組,固定為OXCAFEBABE

2,版本號,主版本號和次版本號決定了Class檔案的檔案格式版本。

3,常量池

     常量池是Class檔案中與其他專案關聯最多的資料型別,也是佔用Class檔案控制元件最大的資料項之一。常量池中主要放置字面量(Literal)和符號引用(Symbolic Reference)。

常量池中的資料包含11中檔案格式型別。特點是:tag(u1,取值為1-12,代表那種型別,tag!=2 )  + 對應的結構資訊

4,訪問標誌、類索引、父類索引、結構索引集合

     在常量池之後是2個位元組的索引標示,用於識別訪問資訊。如ACC_PUBLIC public型別,ACC_INTERFACE 介面型別,ACC_ANNOTATION 這是個註解。

5,之後是欄位表,方法表和屬性表

Class檔案例項

 下面我們來解析Class檔案,使用在學習GOF時的一個例子程式PersonContext.java如下:

package behave.strategy;

public class PersonContext {
	
	private IStrategy st;

	public PersonContext(IStrategy st) {
		this.st = st;
	}
	
	public void fun(){
		st.fun();
	}
}

使用javap命令可以反編譯生成的.class檔案的位元組碼(附帶JDC資訊)
C:\Users\Army>java -version

java version "1.7.0_40"
Java(TM) SE Runtime Environment (build 1.7.0_40-b43)
Java HotSpot(TM) 64-Bit Server VM (build 24.0-b56, mixed mode)

D:\Users\workspace\GOF\target\classes\behave\strategy>javap -v PersonContext.class  

Classfile /D:/Users/workspace/GOF/target/classes/behave/strategy/PersonContext.class
  Last modified 2014-2-13; size 522 bytes
  MD5 checksum f4161c5c60c4b00e481029e8a99f3f0d
  Compiled from "PersonContext.java"
public class behave.strategy.PersonContext
  SourceFile: "PersonContext.java"
  minor version: 0
  major version: 49
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Class              #2             //  behave/strategy/PersonContext
   #2 = Utf8               behave/strategy/PersonContext
   #3 = Class              #4             //  java/lang/Object
   #4 = Utf8               java/lang/Object
   #5 = Utf8               st
   #6 = Utf8               Lbehave/strategy/IStrategy;
   #7 = Utf8               <init>
   #8 = Utf8               (Lbehave/strategy/IStrategy;)V
   #9 = Utf8               Code
  #10 = Methodref          #3.#11         //  java/lang/Object."<init>":()V
  #11 = NameAndType        #7:#12         //  "<init>":()V
  #12 = Utf8               ()V
  #13 = Fieldref           #1.#14         //  behave/strategy/PersonContext.st:Lbehave/strategy/IStrategy
  #14 = NameAndType        #5:#6          //  st:Lbehave/strategy/IStrategy;
  #15 = Utf8               LineNumberTable
  #16 = Utf8               LocalVariableTable
  #17 = Utf8               this
  #18 = Utf8               Lbehave/strategy/PersonContext;
  #19 = Utf8               fun
  #20 = InterfaceMethodref #21.#23        //  behave/strategy/IStrategy.fun:()V
  #21 = Class              #22            //  behave/strategy/IStrategy
  #22 = Utf8               behave/strategy/IStrategy
  #23 = NameAndType        #19:#12        //  fun:()V
  #24 = Utf8               SourceFile
  #25 = Utf8               PersonContext.java
{
  public behave.strategy.PersonContext(behave.strategy.IStrategy);
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=2, args_size=2
         0: aload_0
         1: invokespecial #10                 // Method java/lang/Object."<init>":()V
         4: aload_0
         5: aload_1
         6: putfield      #13                 // Field st:Lbehave/strategy/IStrategy;
         9: return
      LineNumberTable:
        line 7: 0
        line 8: 4
        line 9: 9
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
               0      10     0  this   Lbehave/strategy/PersonContext;
               0      10     1    st   Lbehave/strategy/IStrategy;
   01   25 
  public void fun();
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: getfield      #13                 // Field st:Lbehave/strategy/IStrategy;
         4: invokeinterface #20,  1           // InterfaceMethod behave/strategy/IStrategy.fun:()V
         9: return
      LineNumberTable:
        line 12: 0
        line 13: 9
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
               0      10     0  this   Lbehave/strategy/PersonContext;
}

開啟對應的.class檔案檢視二進位制結構並進行解析如下圖所示


相關推薦

Java Class檔案格式解析例項

JAVA無關性概述 Java語言從剛誕生開始曾提出一個非常著名的宣言:“一次編寫,到處執行(Write Once, Run Anywhere)”。Sun公司和其他虛擬機器公司釋出了許多可以執行在不同作業系統上的虛擬機器,這些虛擬機器都可以載入和執行同一種平臺無關的位元組碼,

深入理解Java Class檔案格式(九)

經過前八篇關於class檔案的部落格, 關於class檔案格式的內容也基本上講完了。 本文是關於class檔案格式的最後一篇。 在這篇部落格中, 將會講解關於方法的幾個屬性。 理解這篇部落格的內容, 對於理解JVM執行引擎起著重要作用。 關於虛擬機器執行引擎有關的內容, 會在本專欄後面的部落格中涉及

深入理解Java Class檔案格式(八)

在本專欄的第一篇文章 深入理解Java虛擬機器到底是什麼 中, 我們主要講解了什麼是虛擬機器, 這篇部落格是對JVM的一個概述。 在隨後的幾篇文章中,一直在講解class檔案格式。 在今天這篇部落格中, 將會繼續講解class檔案中的其他資訊。 在本文中, 將會講解class檔案中的最後一

深入理解Java Class檔案格式(七)

本專欄列前面的一系列部落格, 對Class檔案中的一部分資料項進行了介紹。 本文將會繼續介紹class檔案中未講解的資訊。 先回顧一下上面一篇文章。 在上一篇部落格中, 我們介紹了: this_class    對當前類的描述 super_class  &

深入理解Java Class檔案格式(六)

經過前幾篇文章, 終於將常量池介紹完了, 之所以花這麼大的功夫介紹常量池, 是因為對於理解class檔案格式,常量池是必須要了解的, 因為class檔案中其他地方,大量引用了常量池中的資料項。  對於還不瞭解常量池的讀者, 如果想要深入瞭解class檔案格式, 或者想繼續讀這篇部落格和本專

淺析java class檔案格式

我們知道AOP的生成是代理+反射,其內部是首先對AOP要處理的類進行繼承,然後在要執行切面的地方的方法前或後加上其他的程式碼邏輯,此處就必須要進行動態的class檔案生成,因為Java中萬物皆物件,所以它只會處理物件,那麼必然要將其生成一個新的物件。在Java中要動態生成一

深入理解Java Class檔案格式(五)

到此為止, class檔案中的常量池部分就已經講解完了。 進行一下總結。對於深入理解Java和JVM , 理解class檔案的格式至關重要, 而在class檔案中, 常量池是一項非常重要的資訊。 常量池中有11種資料項, 這個11種資料項儲存了各種資訊, 包括常量字串, 類的資訊, 方法的符號引用, 欄位的符

Java Class檔案格式access_flags 描述的是當前類(或者介面)的訪問修飾符, 如public, private等, 此外, 這裡面還存在一個標誌位, 標誌當前的額這個class描述的

access_flags 描述的是當前類(或者介面)的訪問修飾符, 如public, private等, 此外, 這裡面還存在一個標誌位, 標誌當前的額這個class描述的是類, 還是介面。access_flags 的資訊比較簡單, 下面列出access_flags 中的

Class檔案格式解析

一、Java Class檔案是什麼 《The JavaTM Virtual Machine Specification》(Second Edtion)中有表述:Java Class檔案由8位位元組流組成,所有的16位、32位和64位資料分別通過讀入2個、4個和8個位元組來構

Java class 檔案結構解析

java檔案經過編譯之後就可以形成class檔案。簡而言之,java檔案是我們自己書寫的檔案,也是給我們看的,而class檔案則是給VM看的。但是我們用notepad檢視class檔案時,卻發現那是一串二進位制的檔案。那麼class檔案到底是些啥東西呢? 本質

Java集合-08HashMap原始碼解析使用例項

HashMap 簡介 HahMap是基於hash表的Map介面實現。該實現提供所有可選的對映操作,且允許key和value為null。同時 它不是執行緒安全以及不能保證有序。初始容量(initial capacity)和載入因子(initial capacity)是影響 HashMap的兩個因素。容量

Java Class檔案結構例項分析(下)

發表文章之後,發現很多圖片顯示不了,請閱讀我的公眾號文章,以獲得本文最佳體驗: 本篇我們繼續分析Class檔案結構的方法及屬性部分內容,上節內容回顧請檢視: Class檔案格式資訊 繼續上節例項程式碼 package chapter6; public 

Mp3原理檔案格式解析

1.引言 文 件壓縮技術的日新月異使得MP3成為時下最燙手的音樂格式,優質的音樂隨著0與1的排列迅速散佈到世界各地,撼動人心。何謂MP3?MP3的全稱是 MPEG Audio Layer 3,它是一種高效的計算機音訊編碼方案,它以較大的壓縮比將音訊檔案轉換成較小的副檔名為.MP3的檔案,基本保持原檔案的音質

MP4檔案格式解析MP4檔案的分割演算法

MP4檔案格式的解析,以及MP4檔案的分割演算法   mp4應該算是一種比較複雜的媒體格式了,起源於QuickTime。以前研究的時候就花了一番的功夫,尤其是如何把它完美的融入到視訊點播應用中,更是費盡了心思,主要問題是處理mp4檔案龐大的“媒體頭”。當然,流媒體點播也可以

Java Class檔案結構例項分析(上)

發表文章之後,發現很多圖片顯示不了,請閱讀我的公眾號文章,以獲得本文最佳體驗: 本文假定讀者對Java Class檔案格式有一些基本的瞭解,建議結合相關書籍進行對照閱讀。 Class檔案格式資訊 例項程式碼 package chapter6; public

Java檔案讀寫效能比較總結

Java 之 檔案讀寫及效能比較總結 2014年05月12日 17:56:49 閱讀數:21765  幹Java這麼久,一直在做WEB相關的專案,一些基礎類差不多都已經忘記。經常想得撿起,但總是因為一些原因,不能如願。 其實不是沒有時間,只是有些時候疲於總結,今得空,下定決心

pcd,obj,mtl檔案格式解析

pcd,obj,mtl檔案格式解析 pcd檔案解析 PCD檔案格式並非白費力氣地做重複工作,現有的檔案結構因本身組成的原因不支援由PCL庫引進n維點型別機制處理過程中的某些擴充套件,而PCD檔案格式能夠很好地補足這一點。PCD不是第一個支援3D點雲資料的檔案型別,尤其是計算機圖形

Windows快捷方式檔案格式解析

轉載自:https://blog.csdn.net/cosmoslife/article/details/51898534 大家知道通過IShellLink介面可以得到快捷方式的各種屬性。具體怎麼做,網上有很多文章,這裡就不介紹了。現在主要是分析一下快捷方式檔案的格式,並且自己寫一個解析程式。

java自定義註解解析相關場景實現

註解(Annotation)是java1.5之後提供的一種語法。其主要作用是編譯檢查(比如@override)和程式碼分析(通過程式碼中添加註解,利用註解解析器對添加了註解的程式碼進行分析,獲取想要的結果,一般自定義的註解都是這一種功能)。 1.1 JDK提供的註解 JDK提供的

Class檔案格式總結(十)

到此, 所有關於class檔案格式的重要內容都已經講解完了, 不敢說面面俱到, 但是敢說大部分重要的內容都包含在內了。前前後後用了9篇部落格來專門講解class檔案結構, 為什麼花那麼多的時間和精力來介紹class檔案呢? 簡而言之,因為它很重要。在前面的文章中, 也講到過為什麼對於理解Java體系