Java反射機制

反射

Java的反射就是指程序在運行期間可以拿到一個對象所有的信息。(爲了解決在運行期間,對某個實例一無所知的情況下,如何調用其方法)
class
Method
Field
Constructor

獲取class對象的三種方式:
1.在源碼階段,Class.forName(“全類名”):通過靜態方法獲取class對象,將字節碼文件加載進內存,返回class對象
2.字節碼文件階段,類名.class :通過類名的屬性class獲取;
3.運行階段,對象.getClass():通過調用實例對象提供的方法
注意:getClass對象在object類中,也就意味着所有子類都繼承了這個方法
在這裏插入圖片描述

類加載

類的加載指的是將類的.class文件中的二進制數讀入到內存中去,將其放在運行時數據區的方法區內,然後在堆區創建一個Java.lang.class對象,用來封裝類在方法區內的數據結構。

class是有JVM執行過程中動態加載的。JVM在第一次讀取到一種class類型時,就將其加載進內存。
每加載一種class,JVM就會爲其創建一個class類型的實例,並關聯起來。

類的生命週期分爲七個階段:加載/驗證/準備/解析/初始化/使用/卸載
JVM類加載機制分爲五個部分:加載/驗證/準備/解析/初始化
在這裏插入圖片描述加載:主要完成三件事情:1.通過類的全限定名來獲取此類的二進制字節流;2.將這個類字節流代表的靜態存儲結構轉爲方法區的運行時數據結構;在堆中生成一個代表此類的java.lang.Class對象,作爲訪問方法區這些數據結構的入口。

查找並加載類的二進制文件(也就是.class文件);方法區:存放類的類信息;堆:class文件對應的實例對象。
這個過程主要就是通過類加載器完成。

校驗:此階段主要確保Class文件的字節流中包含的信息符合當前虛擬機的要求,並且不會危害虛擬機的自身安全;
主要包括:1.文件格式驗證:基於字節流的驗證;2.元數據的驗證:基於方法區的存儲結構驗證;3.字節碼驗證:基於方法區的存儲結構驗證;4.符號引用驗證:基於方法區的存儲結構驗證。

準備:爲類變量分配內存,並將其初始化爲默認值(此時爲默認值,在初始化的時候纔會給變量賦值)即在方法區中分配這些變量所使用的內存空間。類變量是static修飾的變量,不包括實例變量,實例變量會在對象實例化的時候隨着對象一起分配在Java堆上。

解析:該階段就是將JVM中常量池內的符號引用替換成直接引用的過程。

初始化:執行類的初始化方法,方法clinit是由編譯器自動生成的,爲靜態變量賦予正確值。
注意:父類定義的靜態代碼塊優先於子類的靜態代碼塊先執行;
子類引用父類的靜態字段不會被初始化。

雙親委派機制

在這裏插入圖片描述雙親委派加載機制:如果一個類加載器接收到了類加載的請求,他首先不會自己去嘗試加載這個請求,而是把請求委託給父加載器去完成,依此向上。因此,所有的類加載請求最終都應該被傳遞到頂層的啓動類加載器中。只有當父加載器在他的搜索範圍中沒有找到所需的類時,即無法完成加載,子類纔會嘗試自己去加載該類。
使用這種機制的好處是:java類隨着他的類加載器一起具備了一種帶有優先層級的層級關係。例如java.lang.Object,它存在於rt.jar中,無論哪一個類加載器要加載這個類,最終都是委派給處於模型最頂端的Bootstrap ClassLoader進行加載,因此Object類在程序的各種類加載環境中都是同一個類。相反,如果沒有雙親委派模型,而是由各個類加載器自行加載的話,如果用戶編寫了一個java.lang.Object的同名類並放在ClassPath中,那系統將會出現多個不同oobject類,程序將混亂。但是如果用了雙親委派模型之後,如果開發者嘗試編寫一個同名的類,可以被編譯但是永遠不會被加載。將最大的權限交給核心類庫,防止API庫被隨意篡改。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章