Java強(qiáng)制轉(zhuǎn)化示例代碼詳解
引入
在Java編程語言中,類型轉(zhuǎn)換(無論是強(qiáng)制類型轉(zhuǎn)換還是自動類型轉(zhuǎn)換)的方向并不是簡單地基于“高位”和“低位”的概念,而是基于數(shù)據(jù)類型的范圍和精度。
基本類型強(qiáng)制轉(zhuǎn)換
1.數(shù)字之間
short s = 100; int i = s; // 自動類型轉(zhuǎn)換,安全 int j = 30000; // 一個大于short類型能表示的最大值的int short k = (short) j; // 強(qiáng)制類型轉(zhuǎn)換,可能導(dǎo)致數(shù)據(jù)丟失
上面給出了兩種數(shù)值轉(zhuǎn)換的概念,第一種是short轉(zhuǎn)成int類型,由于short是16位的,int是32位的,此時(shí)就是低精度轉(zhuǎn)為高精度,所以編譯器會自動進(jìn)行類型轉(zhuǎn)換,是安全的,不用強(qiáng)轉(zhuǎn)(因?yàn)檫@種轉(zhuǎn)換是安全的,不會丟失任何信息,只是簡單地?cái)U(kuò)展了符號位)
而第二種則是讓int類型轉(zhuǎn)成short,高精度轉(zhuǎn)低精度,不安全,強(qiáng)制類型轉(zhuǎn)換,short只能存儲低16位的數(shù)據(jù),高16位的位置就舍棄了,所但凡int的高16位存有數(shù)據(jù),此時(shí)的強(qiáng)轉(zhuǎn)就會發(fā)生數(shù)據(jù)丟失。
所以通常而言,這種高精度強(qiáng)轉(zhuǎn)低精度是沒有意義的。
2.數(shù)字字符之間
引入
以前有涉及過steam,buffer的概念,并且它們本質(zhì)都是數(shù)組。
int c=23456; char d=(char) c; //將int類型的c強(qiáng)轉(zhuǎn)成char類型的d System.out.println(d); //并且能夠解析輸出
steam就是類似如下的一串二進(jìn)制數(shù)字,在解析時(shí)以8位或32位等解析成十進(jìn)制,就可以得到不同的結(jié)果:

int[] arr={23456,23457,34567,23876,32447};
for(int x:arr){//解析輸出
char e=(char) x;
System.out.println(e);
} 【以上就是兩個基本類型強(qiáng)制轉(zhuǎn)換的例子,而且基本類型之間都可以進(jìn)行強(qiáng)轉(zhuǎn),只是有的沒有意義?!?/p>
引用類型的強(qiáng)制轉(zhuǎn)換
引入多態(tài)概念前提
e.g.首先,我們定義一個父類
Animal,并在其中聲明一個方法makeSound,但不在父類中實(shí)現(xiàn)它(可以將它設(shè)為抽象方法,但在這個例子中,我們?yōu)榱撕喕?,讓它返回一個默認(rèn)字符串)。然后,我們創(chuàng)建兩個子類Dog和Cat,它們都繼承自Animal類,并各自實(shí)現(xiàn)了makeSound方法。
// 父類 Animal
class Animal {
// 可以是一個抽象方法,但這里為了簡化,我們提供一個默認(rèn)實(shí)現(xiàn)
public String makeSound() {
return "Some generic animal sound";
}
}
// 子類 Dog 繼承自 Animal
class Dog extends Animal {
@Override
public String makeSound() {
return "Woof! Woof!";
}
}
// 子類 Cat 繼承自 Animal
class Cat extends Animal {
@Override
public String makeSound() {
return "Meow! Meow!";
}
}
public class PolymorphismExample {
public static void main(String[] args) {
// 使用父類類型的引用來指向子類對象
Animal myDog = new Dog();
Animal myCat = new Cat();
// 調(diào)用被重寫的方法,將展示多態(tài)性
System.out.println(myDog.makeSound()); // 輸出: Woof! Woof!
System.out.println(myCat.makeSound()); // 輸出: Meow! Meow!
// 盡管 myDog 和 myCat 都是 Animal 類型的引用,
// 但它們實(shí)際上指向的是 Dog 和 Cat 對象,
// 因此調(diào)用 makeSound 方法時(shí)會執(zhí)行子類中的實(shí)現(xiàn)。
}
}在這個例子中,展示了多態(tài)性的兩個關(guān)鍵方面:
父類引用指向子類對象:
myDog是一個Animal類型的引用,但它實(shí)際上指向了一個Dog對象。同樣,myCat是一個Animal類型的引用,但它指向了一個Cat對象。方法重寫:
Dog和Cat類都重寫了Animal類中的makeSound方法。因此,當(dāng)通過myDog和myCat引用調(diào)用makeSound方法時(shí),會分別調(diào)用Dog和Cat類中的實(shí)現(xiàn)。以上例子展示了多態(tài)所遵守的兩項(xiàng),下面是完整的多態(tài)遵循條件:
要符合多態(tài),通常需要滿足以下幾個條件:
繼承:多態(tài)通常依賴于繼承關(guān)系。在面向?qū)ο缶幊讨?,子類繼承父類,從而可以重用父類的代碼并擴(kuò)展新的功能。多態(tài)性允許我們使用父類類型的引用來引用子類對象。
方法重寫(Override):子類需要重寫父類中的某些方法,以便在調(diào)用這些方法時(shí)能夠表現(xiàn)出不同的行為。方法重寫是多態(tài)性的關(guān)鍵所在,它允許子類提供父類方法的具體實(shí)現(xiàn)。
父類引用指向子類對象:這是多態(tài)性的另一個重要方面。我們可以創(chuàng)建一個父類類型的引用,并將其指向一個子類對象。當(dāng)通過這個引用調(diào)用一個被重寫的方法時(shí),將調(diào)用子類中的該方法實(shí)現(xiàn),而不是父類中的實(shí)現(xiàn)。
接口或抽象類:雖然多態(tài)性不一定需要接口或抽象類,但它們?yōu)槎鄳B(tài)性提供了強(qiáng)大的支持。接口和抽象類可以定義方法簽名,而不提供具體實(shí)現(xiàn)。子類可以實(shí)現(xiàn)這些接口或繼承這些抽象類,并提供具體的方法實(shí)現(xiàn)。這樣,當(dāng)使用接口或抽象類類型的引用來引用子類對象時(shí),就可以實(shí)現(xiàn)多態(tài)性。
運(yùn)行時(shí)類型識別(RTTI, Run-Time Type Identification):在Java等語言中,運(yùn)行時(shí)類型識別是多態(tài)性的基礎(chǔ)之一。它允許程序在運(yùn)行時(shí)確定對象的實(shí)際類型,并根據(jù)這個類型來調(diào)用相應(yīng)的方法。這是通過方法重寫和父類引用指向子類對象來實(shí)現(xiàn)的。
【注意:雖然給出了這么多條件,但是多態(tài)性的核心在于方法重寫和父類引用指向子類對象(句柄可以指向自己類的對象或者自己的子孫后代類的對象)這兩個方面?!?/strong>
【注意:引用類型之間的強(qiáng)制類型轉(zhuǎn)換就沒有這么自由了,會有諸多限制】
如下兩個子類繼承Person父類:


【注意:遵循一個類的句柄可以指向自己類的對象或者自己的子孫后代類的對象】
所以以下兩種表達(dá)方式是錯誤的:
①直接報(bào)錯:

②運(yùn)行時(shí)報(bào)錯:
運(yùn)行時(shí)報(bào)錯是因?yàn)椴环隙鄳B(tài),即“指向自己類的對象或者自己的子孫后代類的對象”,這里表示的是:
將s(指向Child2實(shí)例的Person類型變量)強(qiáng)轉(zhuǎn)換成Child 3,Child2和Child3是兄弟關(guān)系,不符合多態(tài)。

如何解決以下問題呢?(o ∀ o )
有啦??!就用那招!(?∀?(?∀?*)
引入關(guān)鍵字instanceof:
instanceof是一個用于檢查對象是否為特定類或其任何父類的實(shí)例的關(guān)鍵字。這個操作符返回一個布爾值:如果對象是指定類的實(shí)例,或者是該類的任何子類的實(shí)例,則返回true;否則返回false。if (object instanceof ClassName) { // 對象是指定類的實(shí)例或其子類的實(shí)例時(shí)執(zhí)行的代碼 }其中:
object是要檢查的對象ClassName是要檢查的類名(包括接口名)還不理解沒關(guān)系,以下給出一個實(shí)例:
class Animal {}
class Dog extends Animal {}
class Cat extends Animal {}
public class Main {
public static void main(String[] args) {
Animal myDog = new Dog();
//Animal myDog = new Dog(); 創(chuàng)建了一個 Dog 類的實(shí)例,并將其引用賦值給 Animal 類型的變量 myDog。這意味著 myDog 指向的是一個 Dog 對象,但它在編譯時(shí)被視為 Animal 類型。
Animal myCat = new Cat();
// Animal myCat = new Cat(); 類似地,創(chuàng)建了一個 Cat 類的實(shí)例,并將其引用賦值給 Animal 類型的變量 myCat。
System.out.println(myDog instanceof Dog); // 輸出 true
System.out.println(myDog instanceof Animal); // 輸出 true
System.out.println(myDog instanceof Cat); // 輸出 false
System.out.println(myDog instanceof Object); // 輸出 true
System.out.println(null instanceof Animal); // 輸出 false
}
}在這個示例中,
myDog是Dog類的實(shí)例,也是Animal類和Object類的實(shí)例(因?yàn)樗蓄惗祭^承自Object)。因此,myDog instanceof Dog返回true,myDog instanceof Animal也返回true,但myDog instanceof Cat返回false,因?yàn)?nbsp;myDog不是Cat的實(shí)例。同樣地,null不是任何類的實(shí)例,所以null instanceof Animal返回false。
public class Test{
public static void main(String[] mmm) throws Exception{
Child2 x=new Child2();
//Child2 x = new Child2(); 創(chuàng)建了一個 Child2 類的實(shí)例,并將其引用賦值給 Child2 類型的變量 x。
Child3 w=new Child3();
//Child3 w = new Child3(); 創(chuàng)建了一個 Child3 類的實(shí)例,并將其引用賦值給 Child3 類型的變量 w。
//句柄可以指向自己類的對象或者自己的子孫后代類的對象
Person s=x; //父類指子類child2
m1(s);
s=w;
m1(s);
public static void m1(Person s){
Child3 w=null;
if(s instanceof Child3){
//?使用instanceof關(guān)鍵字檢查s是否是Child3的實(shí)例,如果是true,才進(jìn)行下面的強(qiáng)轉(zhuǎn)代碼
//?用instanceof來驗(yàn)證強(qiáng)轉(zhuǎn)?
w=(Child3) s;
}
}
}
}
可以看見上面對m1() 方法進(jìn)行了兩次調(diào)用。
如果 s 指向的是 Child3 實(shí)例(在第二次調(diào)用 m1(s); 時(shí)),條件為真,代碼塊內(nèi)的強(qiáng)轉(zhuǎn)類型轉(zhuǎn)換 w = (Child3) s; 會執(zhí)行。如果 s 指向的是 Child2 實(shí)例(在第一次調(diào)用 m1(s); 時(shí)),條件為假,代碼塊內(nèi)的代碼不會執(zhí)行。
總結(jié)
到此這篇關(guān)于Java強(qiáng)制轉(zhuǎn)化的文章就介紹到這了,更多相關(guān)Java強(qiáng)制轉(zhuǎn)化內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java 實(shí)現(xiàn)MD5加密算法的簡單實(shí)例
這篇文章主要介紹了java 實(shí)現(xiàn)MD5加密算法的簡單實(shí)例的相關(guān)資料,這里提供實(shí)例幫助大家應(yīng)用這樣的加密算法,需要的朋友可以參考下2017-09-09
java讀取配置文件自定義字段(yml、properties)
本文主要介紹了java讀取配置文件自定義字段(yml、properties),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07
java基礎(chǔ)理論Stream的Filter與謂詞邏輯
這篇文章主要為大家介紹了java基礎(chǔ)理論Stream的Filter與謂詞邏輯,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-03-03
Spring中@Autowired和@Resource注解的使用區(qū)別詳解
這篇文章主要介紹了Spring中@Autowired和@Resource注解的使用區(qū)別詳解,@Autowired默認(rèn)根據(jù)type進(jìn)行注入,找到與指定類型兼容的?Bean?并進(jìn)行注入,如果無法通過type匹配到對應(yīng)的?Bean?的話,會根據(jù)name進(jìn)行匹配,如果都匹配不到則拋出異常,需要的朋友可以參考下2023-11-11
springboot項(xiàng)目同時(shí)啟動web服務(wù)和grpc服務(wù)的方法
本文主要介紹了springboot項(xiàng)目同時(shí)啟動web服務(wù)和grpc服務(wù)的方法,通過實(shí)際代碼示例展示了實(shí)現(xiàn),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-02-02
java 父類子類有同名方法時(shí)如何調(diào)用的實(shí)現(xiàn)
這篇文章主要介紹了java 父類子類有同名方法時(shí)如何調(diào)用的實(shí)現(xiàn),具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-09-09

