1. 程式人生 > >淺析java class檔案格式

淺析java class檔案格式

我們知道AOP的生成是代理+反射,其內部是首先對AOP要處理的類進行繼承,然後在要執行切面的地方的方法前或後加上其他的程式碼邏輯,此處就必須要進行動態的class檔案生成,因為Java中萬物皆物件,所以它只會處理物件,那麼必然要將其生成一個新的物件。在Java中要動態生成一個class檔案必須要通過classLoader的defineClass進行,此方法中需要一個bytes陣列和其他的一些引數比如還需要ProtectionDomain,那麼一般會傳遞null那麼會使用預設的ProtectionDomain(這和C++預設引數不一樣,C++預設引數是基本引數型別,這是物件)。

protected final Class<?> defineClass(String name, byte[] b, int off, int len,
					 ProtectionDomain protectionDomain)
	throws ClassFormatError
    {
	check();//檢查ClassLoader是否被初始化,未初始化丟擲未初始化異常
	protectionDomain = preDefineClass(name, protectionDomain);//決定保護域(<span style="font-family: Arial, Helvetica, sans-serif;">protectionDomain 許可權控制,在此方法中生成預設值),check檔名,不能以java.</span>
開頭,因為java.*的檔案都是引導檔案,我們不可以干預
	Class c = null;
        String source = defineClassSourceLocation(protectionDomain);//獲取和CodeSource相關的位置,url是不可變的因此一般返回的是codeSource的位置

	try {
	    c = defineClass1(name, b, off, len, protectionDomain, source);//呼叫native方法生成class檔案,native方法的具體實現與JVM相關
	} catch (ClassFormatError cfe) {
	    c = defineTransformedClass(name, b, off, len, protectionDomain, cfe, source);
	}

	postDefineClass(c, protectionDomain);//給類設定簽名,呼叫本地方法
	return c;
    }
通過上述程式碼可以看到我們要想實現一個動態的類,需要去生成的主要是關於一個類的bytes陣列,那麼此陣列來自於String,那麼我們需要關注的是java的class檔案格式,然後按照檔案格式生成即可,目前比較成熟的jar是asm.java,有興趣的可以讀一下。AMS5.0原始碼和Demo
Java位元組碼檔案格式(學過IOSRuntime的同學有沒有覺得很相似?反正我覺得很像)
   ClassFile {
    	u4 magic;
    	u2 minor_version;
    	u2 major_version;//和mimor構成VMajor.Minor,具體採用哪種由Java的JVM版本決定
    	u2 constant_pool_count;//常量池的內容是pool_count+1,大於0或小於pool_cout是有效的
    	cp_info constant_pool[constant_pool_count-1];//儲存字串常量,包括類、介面的名字,屬性域的名字以及其他與類結構和子類結構相關的常量
    	u2 access_flags;//類或介面的訪問許可權等屬性
    	u2 this_class;
    	u2 super_class;
    	u2 interfaces_count;
    	u2 interfaces[interfaces_count];//類和介面必須要在常量池有描述,並且不可超過255(因為它用一個位元組表示了1-255的個數,內部實現了utf8的轉碼)
    	u2 fields_count;
    	field_info fields[fields_count];
    	u2 methods_count;
    	method_info methods[methods_count];//屬性和方法的描述符請參考表,方法是(引數)返回值
    	u2 attributes_count;//各種資訊的檔案格式
    	attribute_info attributes[attributes_count];
    }
其中u2 u4分別指的是u1, u2, and u4 represent an unsigned one-, two-, or four-byte,是位元組。

屬性表(Flag之間是有關聯的,關聯的形式即類或介面的性質)


屬性表的識別符號


由於常量池裡面保管各種資訊的描述符,因此對於屬性(繼承的不放在本身裡面)和方法以及介面方法的存放是tag+類索引(常量池表中)+nameAndType的索引(常量池表中)

其他的部分是對屬性等方法的定義,有興趣的可以看原文

關於ASM中,博主看了其中關於HelloWorld的demo,裡面需要說明的是ASM通過對位元組碼檔案進行描述來實現動態class檔案生成,他的生成是生成byteArray,那麼裡面關於byteArray是根據class檔案的檔案結構定義的

PS:其中MethodWriter與ClassWriter是相互關聯的物件,ClassWriter裡面的firstMethod和lastMethod是method方法的管理用的是連結串列,他們的初始化採用的是delay方式,此種實現是在MethodWriter中進行的,通過判斷是否為空進行管理。他們可以直接對firstMethod和lastMethod進行賦值而無需考慮中間是否還有其他method原因在於所有的method方法的描述會放入常量池,具體相關還請大家看上面的原文連結。英文原文內容較多,博主只是對其中的開頭部分進行了說明,有想詳細瞭解的建議讀原文。

相關推薦

淺析java class檔案格式

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

深入理解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檔案格式解析及例項

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

深入理解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 檔案淺析 .class檔案格式詳解 欄位方法屬性常量池欄位 class檔案屬性表 資料型別 資料結構

ClassFile { u4 magic;//唯一作用是確定這個檔案是否為一個能被虛擬機器所接受的class檔案。魔數值固定為0xCAFEBABE,不會改變 u2 minor_version;//唯一作用是確定這個檔案是否為一個能被虛擬機器所接受的class檔案。魔數值固定為0xCAFEBABE,不會

Class檔案格式總結(十)

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

java class檔案的載入

java class檔案載入過程:jvm把描述類的資料從class檔案載入(loading)到記憶體(java方法區)中,中間對資料進行校驗(verification)、轉換解析(resolution)和初始化(initialization),最終形成可以被jvm直接使用的Jav

Class 檔案格式詳解

Class 檔案格式詳解 Write once, run everywhere!,我們都知道這是 Java 著名的宣傳口號。不同的作業系統,不同的 CPU 具有不同的指令集,如何做到平臺無關性,依靠的就是 Java 虛擬機器。計算機永遠只能識別 0 和 1組成的二進位制檔案,虛擬機器就是我們編寫的程式碼和計

Class檔案格式實戰:使用ASM動態生成class檔案

概述 本專欄前面的文章,主要詳細講解了Class檔案的格式,並且在上一篇文章中做了總結。 眾所周知, JVM在執行時, 載入並執行class檔案, 這個class檔案基本上都是由我們所寫的java原始檔通過javac編譯而得到的。 但是, 我們有時候會遇到這種情況:在前

JVM學習筆記2:Class檔案格式

一:class檔案概述      Class檔案是JVM的輸入,Java虛擬機器規範中定義了Class檔案的結構。Class檔案是JVM實現平臺 無關、技術無關的基礎。       1:Class檔案是一組以8位元組為單位的位元組流,各個資料專案按順序緊湊排列      

Shell指令碼通過Java class檔案啟停Java程式

通過Shell指令碼啟動和停止Java程式(文章末尾附指令碼和程式原始碼地址) 步驟: 1,通過shell啟動指令碼啟動mainclass(非java -jar的方式) 2,記錄程序id 3,通過shell停止指令碼殺掉程序 示例專案結構和主類程式碼: 將工程編譯成

Java Class檔案結構

平臺無關性和語言無關性 Java在剛剛誕生的時候提出過一個宣傳口號:“一次編寫,到處執行”,這句話充分表達了軟體開發人員對衝破平臺界限的渴求。“與平臺無關”的理想最終實現在作業系統的應用層上:Sun公司及其他虛擬機器提供商釋出了許多可以執行在各種不同平臺上的虛

檢視java class檔案的編譯版本號

用maven做專案依賴管理,依賴了一個其他組開發的一個基礎包。結果,在使用maven進行編譯打包的時候,報了錯: Unsupported major.minor version 51.0。 注:我本機上目前只安裝了 jdk 1.8 使用Eclispse自帶的

Java class檔案的JDK編譯版本號

  比如用UltraEdit(UE)開啟class檔案(如果是在linux,比如Ubuntu下,用$hexdump -C Test.class),你會看到諸如第一行是: 00000000h: CA FE BA BE00 00 32 00 A9 07 00 02 01 00 前四個位元組為固定的 CA FE B

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

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

Java Class檔案的一些解讀

E:\program\JVM\bin\com\gissky\clazz>javap -v Sub.class Classfile /E:/program/JVM/bin/com/gissky/clazz/Sub.class   Last modified 2015-2-22; size 1363 byt