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

JDK15類(lèi)加載、驗(yàn)證、準(zhǔn)備過(guò)程詳解

開(kāi)發(fā) 前端
任何程序都需加載到內(nèi)存才能與CPU進(jìn)行交流,字節(jié)碼.class文件也不例外,加載到內(nèi)存中才可實(shí)例化類(lèi)。

[[379157]]

 使用類(lèi)的準(zhǔn)備工作

任何程序都需加載到內(nèi)存才能與CPU進(jìn)行交流,字節(jié)碼.class文件也不例外,加載到內(nèi)存中才可實(shí)例化類(lèi)。

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

Java的類(lèi)加載器是一個(gè)運(yùn)行時(shí)核心基礎(chǔ)設(shè)施模塊,主要是在啟動(dòng)之初進(jìn)行類(lèi)的加載、鏈接、初始化:

  • Java 類(lèi)加載過(guò)程

Load-加載

由類(lèi)加載器執(zhí)行。

讀取類(lèi)文件(通常在 classpath 所指定的路徑中查找,但classpath也非必須的),查找字節(jié)碼,從而產(chǎn)生二進(jìn)制流,并轉(zhuǎn)為特定數(shù)據(jù)結(jié)構(gòu)。

初步校驗(yàn)cafe babe魔法數(shù)、常量池、文件長(zhǎng)度、是否有父類(lèi)等,然后創(chuàng)建對(duì)應(yīng)類(lèi)的java.lang.Class實(shí)例。

Link-鏈接

將已讀入內(nèi)存的類(lèi)的二進(jìn)制數(shù)據(jù)合并到 JVM 運(yùn)行時(shí)環(huán)境。

包括如下三步:

驗(yàn)證

確保被加載類(lèi)的正確性。驗(yàn)證類(lèi)中的字節(jié)碼,是更詳細(xì)的校驗(yàn),比如final是否合規(guī)、類(lèi)型是否正確、靜態(tài)變量是否合理

準(zhǔn)備

為類(lèi)的static字段分配內(nèi)存,并設(shè)定初始默認(rèn)值,解析類(lèi)和方法確保類(lèi)與類(lèi)之間的相互引用正確性,完成內(nèi)存結(jié)構(gòu)布局

解析

如果需要的話(huà),將解析這個(gè)類(lèi)創(chuàng)建的對(duì)其他類(lèi)的所有引用,將常量池的符號(hào)引用轉(zhuǎn)換成直接引用 。

Init-初始化

執(zhí)行類(lèi)構(gòu)造器,若賦值是通過(guò)其他類(lèi)的靜態(tài)方法來(lái)完成的,則會(huì)馬上解析另類(lèi),在JVM棧中執(zhí)行完畢后通過(guò)返回值進(jìn)行賦值。

類(lèi)加載是一個(gè)將.class字節(jié)碼文件實(shí)例化成Class對(duì)象并進(jìn)行相關(guān)初始化的過(guò)程。

在這個(gè)過(guò)程中,JVM會(huì)初始化繼承樹(shù)上還沒(méi)有被初始化過(guò)的所有父類(lèi),并且會(huì)執(zhí)行這個(gè)鏈路上所有未執(zhí)行過(guò)的靜態(tài)代碼塊、靜態(tài)變量賦值語(yǔ)句等。

某些類(lèi)在使用時(shí),也可以按需由類(lèi)加載器進(jìn)行加載。

全小寫(xiě)的class是關(guān)鍵字,用來(lái)定義類(lèi)

而首字母大寫(xiě)的Class,它是所有class的類(lèi)

這句話(huà)理解起來(lái)有難度,類(lèi)已經(jīng)是現(xiàn)實(shí)世界中某種事物的抽象,為什么這個(gè)抽象還是另外一個(gè)類(lèi)Class的對(duì)象?

示例代碼如下:





第1處說(shuō)明:

Class類(lèi)下的newInstance()在JDK9中已經(jīng)置為過(guò)時(shí),使用getDeclaredConstructor().newInstance()的方式

著重說(shuō)明一下new與newInstance的區(qū)別

new是強(qiáng)類(lèi)型校驗(yàn),可以調(diào)用任何構(gòu)造方法,在使用new操作的時(shí)候,這個(gè)類(lèi)可以沒(méi)有被加載過(guò)

而Class類(lèi)下的newInstance是弱類(lèi)型,只能調(diào)用無(wú)參構(gòu)造方法

  • 如果沒(méi)有默認(rèn)構(gòu)造方法,就拋出InstantiationException異常;
  • 如果此構(gòu)造方法沒(méi)有權(quán)限訪問(wèn),則拋 IllegalAccessException異常

Java 通過(guò)類(lèi)加載器把類(lèi)的實(shí)現(xiàn)與類(lèi)的定義進(jìn)行解耦,所以是實(shí)現(xiàn)面向接口編程、依賴(lài)倒置的必然選擇。

第2處說(shuō)明

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


第3處說(shuō)明: private 成員在類(lèi)外是否可以修改?

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

如果沒(méi)有這一步,則拋出如下異常:

 


1 加載的定位

“加載”是“類(lèi)加載”(Class Loading)過(guò)程的第一步。

1.1 加載過(guò)程

JVM主要做如下事情:

  • 通過(guò)類(lèi)的全限定名(保證全局唯一)獲取該類(lèi)的二進(jìn)制字節(jié)流(class文件)

 在程序運(yùn)行過(guò)程中,當(dāng)要訪問(wèn)一個(gè)類(lèi)時(shí),若發(fā)現(xiàn)這個(gè)類(lèi)尚未被加載,并滿(mǎn)足類(lèi)初始化的條件時(shí),就根據(jù)要被初始化的這個(gè)類(lèi)的全限定名找到該類(lèi)的二進(jìn)制字節(jié)流,開(kāi)始加載過(guò)程。

把類(lèi)加載階段的“通過(guò)類(lèi)的全限定名來(lái)獲取該類(lèi)的二進(jìn)制字節(jié)流”這個(gè)動(dòng)作交給虛擬機(jī)之外的類(lèi)加載器來(lái)完成的好處在于,可自行實(shí)現(xiàn)類(lèi)加載器來(lái)加載其他格式的類(lèi),只要是二進(jìn)制字節(jié)流就行,這就大大增強(qiáng)加載器的靈活性。

  • 將這個(gè)字節(jié)流的靜態(tài)存儲(chǔ)結(jié)構(gòu)轉(zhuǎn)化為方法區(qū)的運(yùn)行時(shí)數(shù)據(jù)結(jié)構(gòu)
  • 在內(nèi)存中創(chuàng)建一個(gè)該類(lèi)的java.lang.Class對(duì)象,作為方法區(qū)該類(lèi)的各種數(shù)據(jù)的訪問(wèn)入口,所以所有類(lèi)都可以調(diào)用 getClass 方法

程序在運(yùn)行中所有對(duì)該類(lèi)的訪問(wèn)都通過(guò)這個(gè)類(lèi)對(duì)象,也就是這個(gè)Class對(duì)象是提供給外界訪問(wèn)該類(lèi)的接口

1.2 加載源

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

  • zip包
  • Jar、War、Ear等
  • 其它文件生成
  • 由JSP文件中生成對(duì)應(yīng)的Class類(lèi)
  • 數(shù)據(jù)庫(kù)中
  • 將二進(jìn)制字節(jié)流存儲(chǔ)至數(shù)據(jù)庫(kù)中,然后在加載時(shí)從數(shù)據(jù)庫(kù)中讀取.有些中間件會(huì)這么做,用來(lái)實(shí)現(xiàn)代碼在集群間分發(fā)
  • 網(wǎng)絡(luò)
  • 從網(wǎng)絡(luò)中獲取二進(jìn)制字節(jié)流,比如Applet
  • 運(yùn)行時(shí)動(dòng)態(tài)計(jì)算生成
  • 動(dòng)態(tài)代理技術(shù),用PRoxyGenerator.generateProxyClass為特定接口生成形式為"*$Proxy"的代理類(lèi)的二進(jìn)制字節(jié)流

1.3 類(lèi)和數(shù)組加載過(guò)程的區(qū)別

數(shù)組也有類(lèi)型,稱(chēng)為“數(shù)組類(lèi)型”,如:

String[] str = new String[10];

這個(gè)數(shù)組的數(shù)組類(lèi)型是Ljava.lang.String,而String只是這個(gè)數(shù)組的元素類(lèi)型。

當(dāng)程序在運(yùn)行過(guò)程中遇到new關(guān)鍵字創(chuàng)建一個(gè)數(shù)組時(shí),由JVM直接創(chuàng)建數(shù)組類(lèi),再由類(lèi)加載器創(chuàng)建數(shù)組中的元素類(lèi)型。

而普通類(lèi)的加載由類(lèi)加載器創(chuàng)建。既可以使用系統(tǒng)提供的引導(dǎo)類(lèi)加載器,也可以由用戶(hù)自定義的類(lèi)加載器完成(即重寫(xiě)一個(gè)類(lèi)加載器的loadClass()方法)

1.4 加載過(guò)程的注意點(diǎn)

JVM規(guī)范并未給出類(lèi)在方法區(qū)中存放的數(shù)據(jù)結(jié)構(gòu)

類(lèi)完成加載后,二進(jìn)制字節(jié)流就以特定的數(shù)據(jù)結(jié)構(gòu)存儲(chǔ)在方法區(qū)中,但存儲(chǔ)的數(shù)據(jù)結(jié)構(gòu)是由虛擬機(jī)自己定義的,虛擬機(jī)規(guī)范并沒(méi)有指定

JVM規(guī)范并沒(méi)有指定Class對(duì)象存放的位置

在二進(jìn)制字節(jié)流以特定格式存儲(chǔ)在方法區(qū)后,JVM會(huì)創(chuàng)建一個(gè)java.lang.Class類(lèi)的對(duì)象,作為本類(lèi)的外部訪問(wèn)接口

既然是對(duì)象就應(yīng)該存放在Java堆中,不過(guò)JVM規(guī)范并沒(méi)有給出限制,不同的虛擬機(jī)根據(jù)自己的需求存放這個(gè)對(duì)象

HotSpot將Class對(duì)象存放在方法區(qū).

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

類(lèi)加載的過(guò)程中每個(gè)步驟的開(kāi)始順序都有嚴(yán)格限制,但每個(gè)步驟的結(jié)束順序沒(méi)有限制.也就是說(shuō),類(lèi)加載過(guò)程中,必須按照如下順序開(kāi)始:

加載 -> 鏈接 -> 初始化

但結(jié)束順序無(wú)所謂,因此由于每個(gè)步驟處理時(shí)間的長(zhǎng)短不一就會(huì)導(dǎo)致有些步驟會(huì)出現(xiàn)交叉

2 驗(yàn)證

驗(yàn)證階段比較耗時(shí),它非常重要但不一定必要(因?yàn)閷?duì)程序運(yùn)行期沒(méi)有影響),如果所運(yùn)行的代碼已經(jīng)被反復(fù)使用和驗(yàn)證過(guò),那么可以使用-Xverify:none參數(shù)關(guān)閉,以縮短類(lèi)加載時(shí)間

2.1 驗(yàn)證的目的

保證二進(jìn)制字節(jié)流中的信息符合虛擬機(jī)規(guī)范,并沒(méi)有安全問(wèn)題

2.2 驗(yàn)證的必要性

雖然Java語(yǔ)言是一門(mén)安全的語(yǔ)言,它能確保程序猿無(wú)法訪問(wèn)數(shù)組邊界以外的內(nèi)存、避免讓一個(gè)對(duì)象轉(zhuǎn)換成任意類(lèi)型、避免跳轉(zhuǎn)到不存在的代碼行.也就是說(shuō),Java語(yǔ)言的安全性是通過(guò)編譯器來(lái)保證的.

但是我們知道,編譯器和虛擬機(jī)是兩個(gè)獨(dú)立的東西,虛擬機(jī)只認(rèn)二進(jìn)制字節(jié)流,它不會(huì)管所獲得的二進(jìn)制字節(jié)流是哪來(lái)的,當(dāng)然,如果是編譯器給它的,那么就相對(duì)安全,但如果是從其它途徑獲得的,那么無(wú)法確保該二進(jìn)制字節(jié)流是安全的。

通過(guò)上文可知,虛擬機(jī)規(guī)范中沒(méi)有限制二進(jìn)制字節(jié)流的來(lái)源,在字節(jié)碼層面上,上述Java代碼無(wú)法做到的都是可以實(shí)現(xiàn)的,至少語(yǔ)義上是可以表達(dá)出來(lái)的,為了防止字節(jié)流中有安全問(wèn)題,需要驗(yàn)證!

2.3 驗(yàn)證的過(guò)程

文件格式驗(yàn)證

驗(yàn)證字節(jié)流是否符合Class文件格式的規(guī)范,并且能被當(dāng)前的虛擬機(jī)處理.

本驗(yàn)證階段是基于二進(jìn)制字節(jié)流進(jìn)行的,只有通過(guò)本階段驗(yàn)證,才被允許存到方法區(qū)

后面的三個(gè)驗(yàn)證階段都是基于方法區(qū)的存儲(chǔ)結(jié)構(gòu)進(jìn)行,不會(huì)再直接操作字節(jié)流.

通過(guò)上文可知,加載開(kāi)始前,二進(jìn)制字節(jié)流還沒(méi)進(jìn)方法區(qū),而加載完成后,二進(jìn)制字節(jié)流已經(jīng)存入方法區(qū)

而在文件格式驗(yàn)證前,二進(jìn)制字節(jié)流尚未進(jìn)入方法區(qū),文件格式驗(yàn)證通過(guò)之后才進(jìn)入方法區(qū)

也就是說(shuō),加載開(kāi)始后,立即啟動(dòng)了文件格式驗(yàn)證,本階段驗(yàn)證通過(guò)后,二進(jìn)制字節(jié)流被轉(zhuǎn)換成特定數(shù)據(jù)結(jié)構(gòu)存儲(chǔ)至方法區(qū)中,繼而開(kāi)始下階段的驗(yàn)證和創(chuàng)建Class對(duì)象等操作

這個(gè)過(guò)程印證了:加載和驗(yàn)證是交叉進(jìn)行的

  • 元數(shù)據(jù)驗(yàn)證

對(duì)字節(jié)碼描述的信息進(jìn)行語(yǔ)義分析,確保符合Java語(yǔ)法規(guī)范。

  • 字節(jié)碼驗(yàn)證

驗(yàn)證過(guò)程的最復(fù)雜的階段。本階段對(duì)數(shù)據(jù)流和控制流(主要為方法體)進(jìn)行語(yǔ)義分析。字節(jié)碼驗(yàn)證將對(duì)類(lèi)的方法進(jìn)行校驗(yàn)分析,保證被校驗(yàn)的方法在運(yùn)行時(shí)不會(huì)做             出危害虛擬機(jī)的事,一個(gè)類(lèi)方法體的字節(jié)碼沒(méi)有通過(guò)字節(jié)碼驗(yàn)證,那一定有問(wèn)題,但若一個(gè)方法通過(guò)了驗(yàn)證,也不能說(shuō)明它一定安全。

  • 符號(hào)引用驗(yàn)證

發(fā)生在JVM將符號(hào)引用轉(zhuǎn)化為直接引用的時(shí)候,這個(gè)轉(zhuǎn)化動(dòng)作發(fā)生在解析階段,對(duì)類(lèi)自身以外的信息進(jìn)行匹配校驗(yàn),確保解析能正常執(zhí)行.

 

責(zé)任編輯:姜華 來(lái)源: JavaEdge
相關(guān)推薦

2021-01-29 06:08:33

JDK15類(lèi)Java

2021-01-29 06:03:29

JDK15JVM類(lèi)加載器

2020-09-17 08:09:16

JDK發(fā)布預(yù)覽

2019-07-24 08:34:35

Java對(duì)象數(shù)據(jù)結(jié)構(gòu)

2024-08-09 11:50:00

2009-07-09 15:27:33

JDK1.6配置

2021-07-05 06:51:43

Java機(jī)制類(lèi)加載器

2025-06-26 03:33:00

2009-07-08 13:22:30

JDK源碼分析Set

2012-11-06 10:19:18

Java自定義加載Java類(lèi)

2020-05-11 15:01:16

JavaJKD 15工具

2024-04-09 08:41:41

JVM類(lèi)加載Java

2020-10-26 11:20:04

jvm類(lèi)加載Java

2009-07-09 14:57:08

JDK環(huán)境配置

2024-06-24 14:52:50

Android類(lèi)加載器

2022-01-14 11:45:40

JVM 虛擬機(jī)Java

2021-02-22 11:51:15

Java開(kāi)發(fā)代碼

2023-08-02 08:38:27

JVM加載機(jī)制

2012-02-14 13:39:57

Java

2021-07-28 10:08:19

類(lèi)加載代碼塊面試
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 91久久国产综合久久91精品网站 | 欧美4p | 午夜视频在线播放 | 国产香蕉视频在线播放 | 亚洲欧洲日韩 | 久久久精品视频免费 | 中文在线观看视频 | 久久精品免费 | 蜜桃精品视频在线 | 日本不卡一区二区三区 | 久久久久久久久久久久久91 | 久久国产精品久久国产精品 | 一区二区久久 | 久久精品伊人 | 欧美日韩国产在线观看 | 成人免费视频一区二区 | 亚洲欧美一区二区三区情侣bbw | 国产偷录叫床高潮录音 | 一区二区三区在线免费 | 一道本视频 | 久久亚洲欧美日韩精品专区 | 亚洲成av | 日韩欧美一区二区三区免费看 | 久久久性色精品国产免费观看 | 国产区一区二区三区 | 免费一级欧美在线观看视频 | 欧美日韩最新 | 亚洲在线中文字幕 | 精品中文字幕久久 | 中文字幕的av| 四虎永久免费黄色影片 | 全免费a级毛片免费看视频免费下 | 男女午夜激情视频 | 婷婷综合在线 | 欧美精品导航 | 午夜视频导航 | 91精品国产综合久久久久久 | 欧美aaaaaaaaaa | 中文字幕在线观看一区二区 | 国产精品视频一 | 天天搞天天操 |