???? 學(xué)習(xí)交流群:
??1:這是孫哥suns給大家的福利!
??2:我們免費(fèi)分享Netty、Dubbo、k8s、Mybatis、Spring...應(yīng)用和源碼級(jí)別的視頻資料
????3:QQ群:583783824 ? ???? ?工作微信:BigTreeJava 拉你進(jìn)微信群,免費(fèi)領(lǐng)??!
????4:本文章內(nèi)容出自上述:Spring應(yīng)用課程!????
????5:以上內(nèi)容,進(jìn)群免費(fèi)領(lǐng)取呦~ ????????
文章目錄
一:方法的調(diào)用
1:概述
2:靜態(tài)鏈接
3:動(dòng)態(tài)鏈接
二:方法的綁定
1:綁定概念
2:早期綁定
3:晚期綁定
三:晚期綁定示例
1:編寫代碼
2:jclasslib查看內(nèi)容
四:早期綁定示例?
1:編寫代碼
2:jclasslib查看內(nèi)容
五:總結(jié)說明
一:方法的調(diào)用
? ? ? ? 我們每天都在寫方法的調(diào)用,但是我們能搞明白其中的原理和JVM當(dāng)中的操作步驟么?這就是本文的意義。
1:概述
? ? ? ? 官方說法:
? ? ? ? 在JVM中,將符號(hào)引用轉(zhuǎn)換為調(diào)用方法的直接引用這個(gè)操作是跟JVM當(dāng)中方法的綁定機(jī)制息息相關(guān)的。
? ? ? ? 說人話:
? ? ? ? 上邊這段話是什么意思?我這里給大家解釋一下,我們javap整理完畢字節(jié)碼文件之后,我們會(huì)可以在任意一個(gè)方法中查看code下的字節(jié)碼指令,很多字節(jié)碼指令的后邊都會(huì)跟#數(shù)字這么一個(gè)概念,這個(gè)就是符號(hào)引用,這個(gè)引用指向常量池。
? ? ? ? 所謂將符號(hào)引用轉(zhuǎn)換為方法的直接引用,就是將這個(gè)字節(jié)碼指令后邊的符號(hào)引用,轉(zhuǎn)變?yōu)檎鎸?shí)的方法。
? ? ? ? 下列中的#3就是符號(hào)引用。
public void methodB();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
Code:
stack=3, locals=1, args_size=1
0: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #6 // String methodB().....
5: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: aload_0
9: invokevirtual #7 // Method methodA:()V
12: aload_0
13: dup
14: getfield #2 // Field num:I
17: iconst_1
18: iadd
19: putfield #2 // Field num:I
22: return
? ? ? ? 從上述找一個(gè)例子的話,就是將偏移地址為9的字節(jié)碼指令后邊的#7這個(gè)符號(hào)引用用真實(shí)的方法字面量代替
2:靜態(tài)鏈接
? ? ? ? 官方說法:
????????當(dāng)一個(gè)字節(jié)碼文件被裝載進(jìn)JVM內(nèi)部時(shí),如果被調(diào)用的目標(biāo)方法在編譯期可知且運(yùn)行期保持不變時(shí)。這種情況下將調(diào)用方法的符號(hào)引用轉(zhuǎn)換為直接引用的過程稱之為靜態(tài)鏈接。
? ? ? ? 說人話:
? ? ? ? 靜態(tài)鏈接:這種方式在編譯階段就已經(jīng)把符號(hào)引用直接轉(zhuǎn)換為了直接引用。
3:動(dòng)態(tài)鏈接
? ? ? ? 官方說法:
????????如果被調(diào)用的方法在編譯期無法被確定下來,也就是說,只能夠在程序運(yùn)行期將調(diào)用方法的符號(hào)引用轉(zhuǎn)換為直接引用,由于這種引用轉(zhuǎn)換過程具備動(dòng)態(tài)性,因此也就被稱之為動(dòng)態(tài)鏈接。
? ? ? ? 說人話:
? ? ? ? 動(dòng)態(tài)鏈接:這種方式在運(yùn)行階段才能把符號(hào)引用直接轉(zhuǎn)換為直接引用。
二:方法的綁定
1:綁定概念
????????綁定是一個(gè)字段、方法或者類在符號(hào)引用被替換為直接引用的過程,這僅僅發(fā)生一次。這個(gè)不論是編譯器確定還是運(yùn)行期確定都只會(huì)發(fā)生一次,不會(huì)修改。
????????對(duì)應(yīng)的方法的綁定機(jī)制為:早期綁定 (Early Bindng)和晚期綁定(Late Binding)。
2:早期綁定
? ? ? ? 官方說法:
????????早期綁定就是指被調(diào)用的目標(biāo)方法如果在編譯期可知,且運(yùn)行期保持不變時(shí)即可將這個(gè)方法與所屬的類型進(jìn)行綁定,這樣一來,由于明確了被調(diào)用的目標(biāo)方法究竟是哪一個(gè),因此也就可以使用靜態(tài)鏈接的方式將符號(hào)引用轉(zhuǎn)換為直接引用。
? ? ? ? 說人話:
? ? ? ? 早期綁定是和我們的靜態(tài)綁定相對(duì)應(yīng)的。
3:晚期綁定
? ? ? ? 官方說法:
????????如果被調(diào)用的方法在編譯期無法被確定下來,只能夠在程序運(yùn)行期根據(jù)實(shí)際的類型綁定相關(guān)的方法,這種綁定方式也就被稱之為晚期綁定
? ? ? ? 說人話:
? ? ? ? 晚期綁定是和我們的動(dòng)態(tài)綁定相對(duì)應(yīng)的。
三:晚期綁定示例
1:編寫代碼
class Animal {
public void eat(){
System.out.println("動(dòng)物進(jìn)食");
}
}
interface Huntable{
void hunt();
}
class Dog extends Animal implements Huntable{
@Override
public void eat(){
System.out.println("狗吃骨頭");
}
@Override
public void hunt() {
System.out.println("捕食耗子,多管閑事");
}
}
class Cat extends Animal implements Huntable{
@Override
public void eat(){
System.out.println("貓吃魚");
}
@Override
public void hunt() {
System.out.println("捕食耗子,天經(jīng)地義");
}
}
public class AnimalTest{
public void showAnimal(Animal animal){
animal.eat();//晚期綁定
}
public void showHunt(Huntable h){
h.hunt();//晚期綁定
}
}
2:jclasslib查看內(nèi)容
四:早期綁定示例?
1:編寫代碼
class Animal {
public void eat(){
System.out.println("動(dòng)物進(jìn)食");
}
}
interface Huntable{
void hunt();
}
class Dog extends Animal implements Huntable{
@Override
public void eat(){
super.eat();//早期綁定
System.out.println("狗吃骨頭");
}
@Override
public void hunt() {
System.out.println("捕食耗子,多管閑事");
}
}
class Cat extends Animal implements Huntable{
public Cat(){
super();//早期綁定
}
public Cat(String name){
this();//早期綁定
}
@Override
public void eat(){
System.out.println("貓吃魚");
}
@Override
public void hunt() {
System.out.println("捕食耗子,天經(jīng)地義");
}
}
public class AnimalTest{
public void showAnimal(Animal animal){
animal.eat();//晚期綁定
}
public void showHunt(Huntable h){
h.hunt();//晚期綁定
}
}
2:jclasslib查看內(nèi)容
? ? ? ? 光標(biāo)放到cat這個(gè)類上查看他的jclasslib
?????????invokeSpecial是早期綁定字節(jié)碼指令,invokevirtual是晚期綁定的字節(jié)碼指令。
五:總結(jié)說明
????????隨著高級(jí)語言的橫空出世,類似于Java一樣的基于面向?qū)ο蟮木幊陶Z言如今越來越多,盡管這類編程語言在語法風(fēng)格上存在一定的差別,但是它們彼此之間始終保持著一個(gè)共性,那就是都支持封裝、繼承和多態(tài)等面向?qū)ο筇匦?/p>
????????既然這一類的編程語言具備多態(tài)特性,那么自然也就具備早期綁定和晚期綁定兩種綁定方式。
????????Java中任何一個(gè)普通的方法其實(shí)都具備虛函數(shù)的特征,也就是運(yùn)行期才能確定下來,它們相當(dāng)于c++語言中的虛函數(shù) (c++中則需要使用關(guān)鍵字virtual來顯式定義)。
????????如果在Java程序中不希望某個(gè)方法擁有虛函數(shù)的特征時(shí),則可以使用關(guān)鍵字final來標(biāo)記這個(gè)方法。也就是一個(gè)方法不想被晚期綁定,直接把他給final修飾即可。
文章目錄
一:OSI通信模型間數(shù)據(jù)傳輸展示
二:應(yīng)用層到會(huì)話層解析
1:應(yīng)用層
2:表現(xiàn)層
3:會(huì)話層
三:傳輸層到物理層解析
1:傳輸層
2:網(wǎng)絡(luò)層
3:數(shù)據(jù)鏈路層、與物理層
一:OSI通信模型間數(shù)據(jù)傳輸展示
? ? ? ? 分析方法可以借鑒下圖模型。發(fā)送方第7第6層到第1上至下傳輸數(shù)據(jù),而接則從第1層第2到第7層由下至上向每個(gè)上一級(jí)分層傳輸數(shù)據(jù)。每個(gè)分層上,在處理由上一層傳過來的數(shù)據(jù)時(shí)可以附上當(dāng)前分層的協(xié)議所必須的“首部”信息。然后接收端對(duì)收到的數(shù)據(jù)進(jìn)行數(shù)據(jù)“首部”與“內(nèi)容”的分離,再轉(zhuǎn)發(fā)給上一分層,并終將發(fā)送端的數(shù)據(jù)恢復(fù)為原狀。
二:應(yīng)用層到會(huì)話層解析
????????假定用戶A要給用戶B 發(fā)送一封內(nèi)容為“早上好”郵件。眾多的位列與各層中的協(xié)議,發(fā)揮著各自的作用,從而實(shí)現(xiàn)郵件的發(fā)送和接收
1:應(yīng)用層
????????用戶A在主機(jī)A上新建一電子件指定收人為 B并發(fā)送內(nèi)容"叔叔好
????????用戶 A輸入“叔叔好”的這一部分就屬于與通信無關(guān)的功能,而將“早上好”的內(nèi)容發(fā)送給收件人 B 則是其與通相關(guān)的功能。因此,此處的“輸入電子郵件內(nèi)容后發(fā)送給目標(biāo)地址”也就相當(dāng)于應(yīng)用層。從用戶輸人完所要發(fā)送的內(nèi)容并點(diǎn)擊“發(fā)送”按的那一開始,就進(jìn)人了應(yīng)用層協(xié)議的處理。該協(xié)議會(huì)在所要傳送數(shù)據(jù)的前端附加一個(gè)首部標(biāo)簽信息。該首部標(biāo)明了郵件內(nèi)容收件人為“B”。
???????? 這一附有首部信息的數(shù)據(jù)傳送給主機(jī) B 以后由該機(jī)上的收發(fā)郵件軟件通過“收信”功能獲取內(nèi)容主機(jī)B上的應(yīng)用收到由主機(jī)A 發(fā)送過來的數(shù)據(jù)后,如果主機(jī) B上收件人的郵箱空間已滿無法接收新的郵件,則會(huì)返回一個(gè)錯(cuò)誤給發(fā)送方。對(duì)這類異常的處理也正屬于應(yīng)用層需要解決的問題。
2:表現(xiàn)層
????????表示層更關(guān)注據(jù)的具體表現(xiàn)形式。所使用的應(yīng)用軟件本身的不同也會(huì)導(dǎo)致數(shù)據(jù)的表現(xiàn)形式截然不同。比如有的字體處理軟件創(chuàng)建的文件只能由該字處器廠商所提供的特定版本的軟件才來打開讀取。
????????解決這類問題有以下幾種方法。首先是利用表示層,將數(shù)據(jù)從“某個(gè)計(jì)算機(jī)特定的數(shù)據(jù)格式”轉(zhuǎn)換為“網(wǎng)絡(luò)通用的標(biāo)準(zhǔn)數(shù)據(jù)格式”后再發(fā)送出去。接收端主機(jī)收到數(shù)據(jù)以后將這些網(wǎng)絡(luò)標(biāo)準(zhǔn)格式的數(shù)據(jù)恢復(fù)為“該計(jì)算機(jī)特定的數(shù)據(jù)格式”然后再進(jìn)行相應(yīng)處理。
????????在前面這個(gè)例子中,由于數(shù)據(jù)被轉(zhuǎn)換為通用標(biāo)準(zhǔn)的格式后再進(jìn)行處理,使得異構(gòu)的機(jī)型之間也能保持?jǐn)?shù)據(jù)的一致性。這也正是表示層的作用所在。即表示層是進(jìn)行“統(tǒng)一的網(wǎng)絡(luò)數(shù)據(jù)格式”與“某一臺(tái)計(jì)算機(jī)或某一軟件特有的數(shù)據(jù)格式”之間相互轉(zhuǎn)換的分層。
????????此例中的“叔叔好”這文字根據(jù)其編碼格式被轉(zhuǎn)換成為了“統(tǒng)一的網(wǎng)絡(luò)數(shù)據(jù)格式”。即便是一段簡(jiǎn)單的文字流,也可以有眾多復(fù)雜的編碼格式。如果未能按照特定格式編碼,那么在接收端就是收到郵件也可能會(huì)是亂碼表示層與表示層之間為了識(shí)別編碼格式也會(huì)附加首部信息,從而將實(shí)際傳輸?shù)臄?shù)據(jù)轉(zhuǎn)交給下一層去處理。
3:會(huì)話層
????????下面,我們來分析在兩端主機(jī)的會(huì)話層之間是如何高效地進(jìn)行數(shù)據(jù)交互、采用何種方法傳輸數(shù)據(jù)的。
????????假定用戶 A 新建了5電子件準(zhǔn)備發(fā)給用戶B這5件的發(fā)可以有很多種。例如,可以每發(fā)一封郵件時(shí)建立一次連接”,隨后斷開連接。還可以一經(jīng)建立好連接后將5 郵件連續(xù)發(fā)送給對(duì)方。甚至可以同時(shí)建立好5個(gè)連接,將5 封郵件同時(shí)發(fā)送給對(duì)方。決定采用何種連接方法是會(huì)話層的主要責(zé)任。會(huì)話層也像應(yīng)用層或表示層那樣,在其收到的數(shù)據(jù)前端附加首部或標(biāo)簽信息后再轉(zhuǎn)發(fā)給下一層。而這些首部或標(biāo)簽中記錄著數(shù)據(jù)傳送順序的信息。
三:傳輸層到物理層解析
1:傳輸層
????????到此為止,我們通過例子說明了在應(yīng)用層寫人的數(shù)據(jù)會(huì)經(jīng)由表示層格式化編碼、再由會(huì)話層標(biāo)記發(fā)送順序后才被發(fā)送出去的大致過程。然而,會(huì)話層只對(duì)何時(shí)建立連接、何時(shí)發(fā)送數(shù)據(jù)等問題進(jìn)行管理,并不具有實(shí)際傳輸數(shù)據(jù)的功能。真正負(fù)責(zé)在網(wǎng)絡(luò)上傳輸具體數(shù)據(jù)的是會(huì)話層以下的“無名英雄”
????????傳輸層主機(jī)A確保與主機(jī) B之間的通信并準(zhǔn)備發(fā)送數(shù)據(jù)。這一過程叫做“建立連接”。有了這個(gè)通信連接就可以使主機(jī) A 發(fā)送的電子郵件到達(dá)主機(jī) B 中,主機(jī) B 的郵件處理程序獲取最終數(shù)據(jù)。此外,當(dāng)通信傳輸結(jié)束后,有必要將連接斷開。
????????如上,進(jìn)行建立連接或斷開連接的處理,在兩個(gè)主機(jī)之間創(chuàng)建邏輯上的通信連接即是傳輸層的主要作用。此外,傳輸層為確保所傳輸?shù)臄?shù)據(jù)到達(dá)目標(biāo)地址會(huì)在通信兩端的計(jì)算機(jī)之間進(jìn)行確認(rèn),如果數(shù)據(jù)沒有到達(dá),它會(huì)負(fù)責(zé)進(jìn)行重發(fā)。
????????例如,主機(jī) A 將“早上好”這一數(shù)據(jù)發(fā)送給機(jī) B。期間可能會(huì)為某原因?qū)е聰?shù)據(jù)被破壞,或由于發(fā)生某種網(wǎng)絡(luò)異常致使只有一部分?jǐn)?shù)據(jù)到達(dá)目標(biāo)地址。假設(shè)主機(jī) B 只收到了“早上”這一部分?jǐn)?shù)據(jù),那么它會(huì)在收到數(shù)據(jù)后將自已沒有收到“早上”之后那部分?jǐn)?shù)據(jù)的事實(shí)告知主機(jī) A。主機(jī)A得知這個(gè)情后就會(huì)將后面的“好”重發(fā)給主機(jī) B,并再次確認(rèn)對(duì)端是否收到。
????????這就好比人們?nèi)粘?huì)話中的確認(rèn)語句:“對(duì)了,你剛才說什么來著?”計(jì)算機(jī)通信協(xié)議其實(shí)并沒有想象中那么晦澀難懂,其基本原理是與我們的日常生活緊密相連、大同小異的。
????????由此可見,保證數(shù)據(jù)傳輸?shù)目煽啃允莻鬏攲拥囊粋€(gè)重要作用。為了確保可靠性,在這一層也會(huì)為所要傳輸?shù)臄?shù)據(jù)附加首部以識(shí)別這一分層的數(shù)據(jù)。然而,實(shí)際上將數(shù)據(jù)傳輸給對(duì)端的處理是由網(wǎng)絡(luò)層來完成的。
????????傳輸層作用就是:確立鏈接、斷開鏈接、保證傳輸準(zhǔn)確性和完整性。
2:網(wǎng)絡(luò)層
????????網(wǎng)絡(luò)層的作用是在網(wǎng)絡(luò)與網(wǎng)絡(luò)相互連接的環(huán)境中,將數(shù)據(jù)從發(fā)送端主機(jī)發(fā)送到接收端主機(jī)。如圖127 所示,兩端機(jī)之間然有眾多數(shù)據(jù)鏈路,能夠?qū)?shù)據(jù)從主機(jī)A送到主機(jī) B也都是網(wǎng)絡(luò)層的勞。
????????網(wǎng)絡(luò)層的作用就是:主機(jī)A到主機(jī)B的數(shù)據(jù)通信處理
????????在實(shí)際發(fā)送數(shù)據(jù)時(shí),目的地址"至關(guān)重要。這個(gè)地址是進(jìn)行通信的網(wǎng)絡(luò)中唯一指定的序號(hào)。也可以把它想象為我們?nèi)粘I钪惺褂玫碾娫捥?hào)碼。只要這個(gè)目標(biāo)地址確定了,就可以在眾多計(jì)算機(jī)中選出該目標(biāo)地址所對(duì)應(yīng)的計(jì)算機(jī)發(fā)送數(shù)據(jù)?;谶@個(gè)地址,就可以在網(wǎng)絡(luò)層進(jìn)行數(shù)據(jù)包的發(fā)送處理。而有了地址和網(wǎng)絡(luò)層的包發(fā)送處理,就可以將數(shù)據(jù)發(fā)送到世界上任何一臺(tái)互連設(shè)備。網(wǎng)絡(luò)層中也會(huì)將其從上層收到的數(shù)據(jù)和地址信息等一起發(fā)送給下面的數(shù)據(jù)鏈路層,進(jìn)行后面的處理。
????????傳輸層與網(wǎng)絡(luò)層的關(guān)系
????????在不同的網(wǎng)絡(luò)體系結(jié)構(gòu)下,網(wǎng)絡(luò)層有時(shí)也不能保證數(shù)據(jù)的可達(dá)性。例如在相當(dāng)于TCP/IP 網(wǎng)絡(luò)層的 IP 協(xié)議中,就不能保證數(shù)據(jù)一定會(huì)發(fā)送到對(duì)端地址。因此,數(shù)據(jù)傳送過程中出現(xiàn)數(shù)據(jù)丟失、順序混亂等問題可能性會(huì)大大增加。像這樣沒有可靠性傳輸要求的網(wǎng)絡(luò)層中,可以由傳輸層負(fù)責(zé)提供“正確傳輸數(shù)據(jù)的處理”。TCP/IP 中,網(wǎng)絡(luò)層與傳輸層相互協(xié)作以確保數(shù)據(jù)包能夠傳送到世界各地,實(shí)現(xiàn)可靠傳輸。
????????每個(gè)分層的作用與功能越清晰,規(guī)范協(xié)議的具體內(nèi)容就越簡(jiǎn)單,實(shí)現(xiàn)”這些具體協(xié)議的工作也將會(huì)更加輕松。
3:數(shù)據(jù)鏈路層、與物理層
????????通信傳輸實(shí)際上是通過物理的傳輸介質(zhì)實(shí)現(xiàn)的。數(shù)據(jù)鏈路層的作用就是在這些通過傳輸介質(zhì)互連的設(shè)備之間進(jìn)行數(shù)據(jù)處理。
?????????物理層中,將數(shù)據(jù)的0轉(zhuǎn)換為電壓和脈沖光傳輸給物理的傳輸介,而相互直連的設(shè)備之間使用地址實(shí)現(xiàn)傳輸。這種地址稱為 MAC地址,也可稱為物理地址或硬件地址。采用 MAC 地址,目的是為了識(shí)別連接到同一個(gè)傳輸介質(zhì)上的設(shè)備。因此,在這一分層中將包含 MAC 地信息的部附加到從網(wǎng)路層轉(zhuǎn)發(fā)過來的數(shù)據(jù)上,將其發(fā)送到網(wǎng)絡(luò)。
????????網(wǎng)絡(luò)層與數(shù)據(jù)鏈路層都是基于目標(biāo)地址將數(shù)據(jù)發(fā)送給接收端的,但是網(wǎng)絡(luò)層負(fù)責(zé)將整個(gè)數(shù)據(jù)發(fā)送給最終目標(biāo)地址,而數(shù)據(jù)鏈路層則只負(fù)責(zé)發(fā)送一個(gè)分段內(nèi)的數(shù)據(jù)。
????????主機(jī)B端的處理接收端主機(jī) B 上的處理流正好與主機(jī)A,它從理層開始將接收到的數(shù)據(jù)逐層發(fā)給上一分層進(jìn)行處理,從而使用戶 B在 B用客戶端軟件接收用戶 A發(fā)送過來的郵件,并可以讀取相應(yīng)內(nèi)容為“早上好”如上所述,讀者可以將通信網(wǎng)絡(luò)的功能分層來思考。每個(gè)分層上的協(xié)議規(guī)定了該分層中數(shù)據(jù)首部的格式以及首部與處理數(shù)據(jù)的順序。文章來源:http://www.zghlxwxcb.cn/news/detail-708314.html
文章參考自:圖解TCP/IP協(xié)議圖書文章來源地址http://www.zghlxwxcb.cn/news/detail-708314.html
到了這里,關(guān)于詳解TCP/IP協(xié)議第三篇:通信數(shù)據(jù)在OSI通信模型的上下傳輸?shù)奈恼戮徒榻B完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!