Java強(qiáng)制類型轉(zhuǎn)換原理詳解(父類轉(zhuǎn)子類、子類轉(zhuǎn)父類)
前言
在Java中,對象的強(qiáng)制轉(zhuǎn)換(也稱為類型轉(zhuǎn)換)是將一個(gè)對象的引用轉(zhuǎn)換為另一個(gè)類的引用,前提是這兩個(gè)類之間存在繼承或?qū)崿F(xiàn)關(guān)系。強(qiáng)制轉(zhuǎn)換可能會導(dǎo)致運(yùn)行時(shí)異常,因?yàn)樵谵D(zhuǎn)換的過程中,如果對象的實(shí)際類型與轉(zhuǎn)換的目標(biāo)類型不兼容,就會拋出ClassCastException異常。
子類轉(zhuǎn)父類
Son s = new Son(); // 類型提升 Father f = (Father)s;//可以
分析: 子類繼承父類,就擁有了父類的一切。某種程度上說,兒子可以代替爸爸,爸爸能做的事兒子也可以做。子類轉(zhuǎn)父類后,父類對象f引用指向子類對象,所以其本質(zhì)任然是子類,f只能調(diào)用父類的方法,如果子類重寫了父類的方法,則調(diào)用的是子類的方法(多態(tài)性)
父類轉(zhuǎn)子類
1. 真實(shí)父類對象轉(zhuǎn)子類對象,報(bào)ClassCastException異常
Father f = new Father(); Son s = (Son)f;//出錯(cuò) ClassCastException
分析: 創(chuàng)建一個(gè)父類的實(shí)例,想要強(qiáng)制把父類對象轉(zhuǎn)換成子類的對象,是不行的。父親有的,通過繼承兒子也有,反過來兒子有的父親卻不一定有。
2. “假”父類對象轉(zhuǎn)子類對象,可以
Father f = new Son(); Son s = (Son)f;//可以
分析:只有父類對象本身就是用子類new出來的時(shí)候, 才可以在將來被強(qiáng)制轉(zhuǎn)換為子類對象。這個(gè)時(shí)候父類的本質(zhì)依然是子類對象(兒子只是裝成了爸爸),子類有的屬性f都擁有,只是f暫時(shí)不能操作子類特有的屬性,所以可以轉(zhuǎn)換回為子類對象(變回兒子本身)
底層實(shí)現(xiàn)原理
底層原理是通過虛擬機(jī)中的類型檢查和類型信息來實(shí)現(xiàn)的。當(dāng)進(jìn)行強(qiáng)制類型轉(zhuǎn)換時(shí),虛擬機(jī)會在運(yùn)行時(shí)檢查對象的實(shí)際類型是否與轉(zhuǎn)換的目標(biāo)類型兼容。如果是兼容的,就會將對象引用轉(zhuǎn)換為目標(biāo)類型的引用,否則會拋出ClassCastException異常。
在Java中,對象的類型信息是通過兩種主要機(jī)制來處理的:對象頭和虛方法表。
對象頭:每個(gè)Java對象都有一個(gè)對象頭,其中包含了一些用于虛擬機(jī)處理對象的元數(shù)據(jù)。對象頭中包含了一個(gè)指向類元數(shù)據(jù)的指針(指向?qū)ο蟮念惖男畔ⅲ_@使得虛擬機(jī)可以在運(yùn)行時(shí)確定對象的實(shí)際類型。
虛方法表:對于每個(gè)類,Java虛擬機(jī)會維護(hù)一個(gè)虛方法表,其中包含了類的虛方法的地址。虛方法表允許在運(yùn)行時(shí)動態(tài)地解析方法調(diào)用,而不是在編譯時(shí)靜態(tài)地綁定。通過虛方法表,Java虛擬機(jī)可以找到并調(diào)用對象的實(shí)際方法。
在進(jìn)行強(qiáng)制類型轉(zhuǎn)換時(shí),虛擬機(jī)會首先檢查對象頭中指向類元數(shù)據(jù)的指針,然后查找目標(biāo)類型的類信息。如果目標(biāo)類型是源類型的子類(或?qū)崿F(xiàn)了源類型的接口),那么轉(zhuǎn)換是有效的。虛擬機(jī)會根據(jù)實(shí)際類型來調(diào)整對象引用的指針,使其指向目標(biāo)類型的類信息和虛方法表,從而實(shí)現(xiàn)類型轉(zhuǎn)換。
然而,如果目標(biāo)類型不是源類型的子類(或未實(shí)現(xiàn)源類型的接口),虛擬機(jī)將無法進(jìn)行有效的轉(zhuǎn)換,這時(shí)會拋出ClassCastException異常。
總結(jié):Java對象的強(qiáng)制類型轉(zhuǎn)換是通過虛擬機(jī)在運(yùn)行時(shí)檢查對象的實(shí)際類型,并根據(jù)類型信息來調(diào)整對象引用的指針來實(shí)現(xiàn)的。這樣的機(jī)制使得Java具有動態(tài)類型的特性,但也需要開發(fā)人員在進(jìn)行類型轉(zhuǎn)換時(shí)注意類型的兼容性,以避免ClassCastException異常。
總結(jié)
到此這篇關(guān)于Java強(qiáng)制類型轉(zhuǎn)換原理的文章就介紹到這了,更多相關(guān)Java強(qiáng)制類型轉(zhuǎn)換內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
關(guān)于SpringBoot整合RabbitMQ實(shí)現(xiàn)死信隊(duì)列
這篇文章主要介紹了關(guān)于SpringBoot整合RabbitMQ實(shí)現(xiàn)死信隊(duì)列,死信隊(duì)列實(shí)際上就是一個(gè)普通的隊(duì)列,只是這個(gè)隊(duì)列跟死信交換機(jī)進(jìn)行了綁定,用來存放死信而已,需要的朋友可以參考下2023-05-05
JAVA發(fā)送HTTP請求的多種方式詳細(xì)總結(jié)
目前做項(xiàng)目中有一個(gè)需求是這樣的,需要通過Java發(fā)送url請求,查看該url是否有效,這時(shí)我們可以通過獲取狀態(tài)碼來判斷,下面這篇文章主要給大家介紹了關(guān)于JAVA發(fā)送HTTP請求的多種方式總結(jié)的相關(guān)資料,需要的朋友可以參考下2023-01-01
Java介紹多線程計(jì)算階乘實(shí)現(xiàn)方法
這篇文章主要為大家詳細(xì)介紹了Java多線程計(jì)算階乘的實(shí)現(xiàn),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-06-06
springboot線程池監(jiān)控的簡單實(shí)現(xiàn)
本文主要介紹了springboot線程池監(jiān)控的簡單實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01
設(shè)計(jì)模式系列之組合模式及其在JDK和MyBatis源碼中的運(yùn)用詳解
這篇文章主要介紹了組合模式及其在JDK和MyBatis源碼中的運(yùn)用,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-09-09
mybatis的ParamNameResolver參數(shù)名稱解析
這篇文章主要為大家介紹了mybatis的ParamNameResolver參數(shù)名稱解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08

