成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

JDK15類加載、驗證、準備過程詳解

開發 前端
任何程序都需加載到內存才能與CPU進行交流,字節碼.class文件也不例外,加載到內存中才可實例化類。

[[379157]]

 使用類的準備工作

任何程序都需加載到內存才能與CPU進行交流,字節碼.class文件也不例外,加載到內存中才可實例化類。

ClassLoader的使命就是提前加載.class 類文件到內存,在加載類時,使用的Parents Delegation Model(溯源委派模型)。

Java的類加載器是一個運行時核心基礎設施模塊,主要是在啟動之初進行類的加載、鏈接、初始化:

  • Java 類加載過程

Load-加載

由類加載器執行。

讀取類文件(通常在 classpath 所指定的路徑中查找,但classpath也非必須的),查找字節碼,從而產生二進制流,并轉為特定數據結構。

初步校驗cafe babe魔法數、常量池、文件長度、是否有父類等,然后創建對應類的java.lang.Class實例。

Link-鏈接

將已讀入內存的類的二進制數據合并到 JVM 運行時環境。

包括如下三步:

驗證

確保被加載類的正確性。驗證類中的字節碼,是更詳細的校驗,比如final是否合規、類型是否正確、靜態變量是否合理

準備

為類的static字段分配內存,并設定初始默認值,解析類和方法確保類與類之間的相互引用正確性,完成內存結構布局

解析

如果需要的話,將解析這個類創建的對其他類的所有引用,將常量池的符號引用轉換成直接引用 。

Init-初始化

執行類構造器,若賦值是通過其他類的靜態方法來完成的,則會馬上解析另類,在JVM棧中執行完畢后通過返回值進行賦值。

類加載是一個將.class字節碼文件實例化成Class對象并進行相關初始化的過程。

在這個過程中,JVM會初始化繼承樹上還沒有被初始化過的所有父類,并且會執行這個鏈路上所有未執行過的靜態代碼塊、靜態變量賦值語句等。

某些類在使用時,也可以按需由類加載器進行加載。

全小寫的class是關鍵字,用來定義類

而首字母大寫的Class,它是所有class的類

這句話理解起來有難度,類已經是現實世界中某種事物的抽象,為什么這個抽象還是另外一個類Class的對象?

示例代碼如下:





第1處說明:

Class類下的newInstance()在JDK9中已經置為過時,使用getDeclaredConstructor().newInstance()的方式

著重說明一下new與newInstance的區別

new是強類型校驗,可以調用任何構造方法,在使用new操作的時候,這個類可以沒有被加載過

而Class類下的newInstance是弱類型,只能調用無參構造方法

  • 如果沒有默認構造方法,就拋出InstantiationException異常;
  • 如果此構造方法沒有權限訪問,則拋 IllegalAccessException異常

Java 通過類加載器把類的實現與類的定義進行解耦,所以是實現面向接口編程、依賴倒置的必然選擇。

第2處說明

可以使用類似的方式獲取其他聲明,如注解、方法等


第3處說明: private 成員在類外是否可以修改?

通過setccessible(true),即可使用Class類的set方法修改其值

如果沒有這一步,則拋出如下異常:

 


1 加載的定位

“加載”是“類加載”(Class Loading)過程的第一步。

1.1 加載過程

JVM主要做如下事情:

  • 通過類的全限定名(保證全局唯一)獲取該類的二進制字節流(class文件)

 在程序運行過程中,當要訪問一個類時,若發現這個類尚未被加載,并滿足類初始化的條件時,就根據要被初始化的這個類的全限定名找到該類的二進制字節流,開始加載過程。

把類加載階段的“通過類的全限定名來獲取該類的二進制字節流”這個動作交給虛擬機之外的類加載器來完成的好處在于,可自行實現類加載器來加載其他格式的類,只要是二進制字節流就行,這就大大增強加載器的靈活性。

  • 將這個字節流的靜態存儲結構轉化為方法區的運行時數據結構
  • 在內存中創建一個該類的java.lang.Class對象,作為方法區該類的各種數據的訪問入口,所以所有類都可以調用 getClass 方法

程序在運行中所有對該類的訪問都通過這個類對象,也就是這個Class對象是提供給外界訪問該類的接口

1.2 加載源

JVM規范對于加載過程給予了較大的寬松度。一般二進制字節流都從已經編譯好的本地class文件中讀取,此外還可以從以下地方讀取

  • zip包
  • Jar、War、Ear等
  • 其它文件生成
  • 由JSP文件中生成對應的Class類
  • 數據庫中
  • 將二進制字節流存儲至數據庫中,然后在加載時從數據庫中讀取.有些中間件會這么做,用來實現代碼在集群間分發
  • 網絡
  • 從網絡中獲取二進制字節流,比如Applet
  • 運行時動態計算生成
  • 動態代理技術,用PRoxyGenerator.generateProxyClass為特定接口生成形式為"*$Proxy"的代理類的二進制字節流

1.3 類和數組加載過程的區別

數組也有類型,稱為“數組類型”,如:

String[] str = new String[10];

這個數組的數組類型是Ljava.lang.String,而String只是這個數組的元素類型。

當程序在運行過程中遇到new關鍵字創建一個數組時,由JVM直接創建數組類,再由類加載器創建數組中的元素類型。

而普通類的加載由類加載器創建。既可以使用系統提供的引導類加載器,也可以由用戶自定義的類加載器完成(即重寫一個類加載器的loadClass()方法)

1.4 加載過程的注意點

JVM規范并未給出類在方法區中存放的數據結構

類完成加載后,二進制字節流就以特定的數據結構存儲在方法區中,但存儲的數據結構是由虛擬機自己定義的,虛擬機規范并沒有指定

JVM規范并沒有指定Class對象存放的位置

在二進制字節流以特定格式存儲在方法區后,JVM會創建一個java.lang.Class類的對象,作為本類的外部訪問接口

既然是對象就應該存放在Java堆中,不過JVM規范并沒有給出限制,不同的虛擬機根據自己的需求存放這個對象

HotSpot將Class對象存放在方法區.

加載階段和鏈接階段是交叉的

類加載的過程中每個步驟的開始順序都有嚴格限制,但每個步驟的結束順序沒有限制.也就是說,類加載過程中,必須按照如下順序開始:

加載 -> 鏈接 -> 初始化

但結束順序無所謂,因此由于每個步驟處理時間的長短不一就會導致有些步驟會出現交叉

2 驗證

驗證階段比較耗時,它非常重要但不一定必要(因為對程序運行期沒有影響),如果所運行的代碼已經被反復使用和驗證過,那么可以使用-Xverify:none參數關閉,以縮短類加載時間

2.1 驗證的目的

保證二進制字節流中的信息符合虛擬機規范,并沒有安全問題

2.2 驗證的必要性

雖然Java語言是一門安全的語言,它能確保程序猿無法訪問數組邊界以外的內存、避免讓一個對象轉換成任意類型、避免跳轉到不存在的代碼行.也就是說,Java語言的安全性是通過編譯器來保證的.

但是我們知道,編譯器和虛擬機是兩個獨立的東西,虛擬機只認二進制字節流,它不會管所獲得的二進制字節流是哪來的,當然,如果是編譯器給它的,那么就相對安全,但如果是從其它途徑獲得的,那么無法確保該二進制字節流是安全的。

通過上文可知,虛擬機規范中沒有限制二進制字節流的來源,在字節碼層面上,上述Java代碼無法做到的都是可以實現的,至少語義上是可以表達出來的,為了防止字節流中有安全問題,需要驗證!

2.3 驗證的過程

文件格式驗證

驗證字節流是否符合Class文件格式的規范,并且能被當前的虛擬機處理.

本驗證階段是基于二進制字節流進行的,只有通過本階段驗證,才被允許存到方法區

后面的三個驗證階段都是基于方法區的存儲結構進行,不會再直接操作字節流.

通過上文可知,加載開始前,二進制字節流還沒進方法區,而加載完成后,二進制字節流已經存入方法區

而在文件格式驗證前,二進制字節流尚未進入方法區,文件格式驗證通過之后才進入方法區

也就是說,加載開始后,立即啟動了文件格式驗證,本階段驗證通過后,二進制字節流被轉換成特定數據結構存儲至方法區中,繼而開始下階段的驗證和創建Class對象等操作

這個過程印證了:加載和驗證是交叉進行的

  • 元數據驗證

對字節碼描述的信息進行語義分析,確保符合Java語法規范。

  • 字節碼驗證

驗證過程的最復雜的階段。本階段對數據流和控制流(主要為方法體)進行語義分析。字節碼驗證將對類的方法進行校驗分析,保證被校驗的方法在運行時不會做             出危害虛擬機的事,一個類方法體的字節碼沒有通過字節碼驗證,那一定有問題,但若一個方法通過了驗證,也不能說明它一定安全。

  • 符號引用驗證

發生在JVM將符號引用轉化為直接引用的時候,這個轉化動作發生在解析階段,對類自身以外的信息進行匹配校驗,確保解析能正常執行.

 

責任編輯:姜華 來源: JavaEdge
相關推薦

2021-01-29 06:08:33

JDK15Java

2021-01-29 06:03:29

JDK15JVM類加載器

2020-09-17 08:09:16

JDK發布預覽

2019-07-24 08:34:35

Java對象數據結構

2009-07-09 15:27:33

JDK1.6配置

2024-08-09 11:50:00

2021-07-05 06:51:43

Java機制類加載器

2025-06-26 03:33:00

2009-07-08 13:22:30

JDK源碼分析Set

2012-11-06 10:19:18

Java自定義加載Java類

2020-05-11 15:01:16

JavaJKD 15工具

2024-04-09 08:41:41

JVM類加載Java

2020-10-26 11:20:04

jvm類加載Java

2009-07-09 14:57:08

JDK環境配置

2024-06-24 14:52:50

Android類加載器

2022-01-14 11:45:40

JVM 虛擬機Java

2021-02-22 11:51:15

Java開發代碼

2023-08-02 08:38:27

JVM加載機制

2012-02-14 13:39:57

Java

2021-07-28 10:08:19

類加載代碼塊面試
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产乱码精品一区二区三区忘忧草 | 美女网站视频免费黄 | 一级日韩 | 亚洲在线一区二区 | 久久成人精品一区二区三区 | 日韩欧美手机在线 | 懂色av一区二区三区在线播放 | 亚洲九九色| 精品一区二区三区在线观看国产 | 亚洲综合色站 | 国产视频福利一区 | 国产精品久久久久久久午夜片 | 欧美成人a∨高清免费观看 欧美日韩中 | 亚洲成人精品一区 | 国产区在线观看 | 亚洲精品久久久久中文字幕二区 | 91国在线观看 | 五月天婷婷丁香 | 欧美福利久久 | 亚洲一区二区电影网 | 超碰av在线 | 91视频88av| 久久国产99 | 91亚洲精 | 国产一区二区三区久久久久久久久 | 可以在线看的黄色网址 | 99精品视频在线观看 | 一级毛片在线播放 | 日本高清视频在线播放 | 99国产精品一区二区三区 | 精品国产一区二区三区久久影院 | 国产日韩精品在线 | 国产乱码精品1区2区3区 | 中文字幕 欧美 日韩 | av一区二区三区 | 日本午夜精品一区二区三区 | 中文字幕一区二区在线观看 | 91精品国产综合久久久动漫日韩 | 日本不卡一区二区三区 | 国产精品爱久久久久久久 | 日韩精品一区二区三区在线观看 |