【解惑】Java型別間的轉型
★ 基本資料型別間的轉換
1、Java要做到平臺無關性,所有的基本資料型別所佔的位元組數量均是固定的。
boolean ——1/8位元組(1 bit) byte —— 1位元組 char —— 2位元組 short —— 2位元組
int —— 4位元組 long —— 8位元組 float —— 4位元組 double —— 8位元組
2、基本資料型別間的轉換
(1) 所佔位元組數相對少的基本型別可以自動向位元組數相對多的轉換。
- byte c=(byte)-1; //強制轉化為byte型
- int i=c; //自動轉化為整型
- System.out.println(i);//列印結果:-1
byte c=(byte)-1; //強制轉化為byte型
int i=c; //自動轉化為整型
System.out.println(i);//列印結果:-1
比如上面的byte型可以自動轉化為int型,但這種轉化是帶符號擴充套件的。因為byte是有符號型別。這裡有一個例外,就是char,它是一個無符號型別,因此自動擴充套件成int、long等型別時是不帶符號擴充套件的。
Java程式碼- char
- int i=c; //自動轉化為整型
- System.out.println(i); //列印結果:65535
char c=(char)-1;
int i=c; //自動轉化為整型
System.out.println(i); //列印結果:65535
上面的程式碼首先將整型0xFFFFFFFF(32bits)強制型別截短為0xFFFF(16bits)。而這個數的型別是char,那麼它表示的數是65535,擴充套件成int型別的時候是無符號擴充套件,高位補0,因此變數i=0x0000FFFF(65536)。
(2) 所佔位元組數多的向位元組數少的轉換要強制執行。
大範圍型別多出的bit將會被截去。
- int i=10000;
- byte j=(byte)i; //4位元組強制轉化為1位元組
- System.out.println(j);//列印結果: 16
int i=10000;
byte j=(byte)i; //4位元組強制轉化為1位元組
System.out.println(j);//列印結果: 16
(3) 位元組一樣多的,long向double型別轉化也需要強制型別轉化,反向不需要。
(4) boolean型不能與其他任何數值型別之間轉換。
★ 類型別間的轉換
這裡有一句很經典的話:男人絕對是人,人可能不是男人,只有原來是男人的人才有希望變回男人。
1、類型別的自動轉換,只能在繼承層次中自下而上的自動轉換(向上轉型),即子類自動轉換為父類。
Java程式碼- //自動向上轉型
- class Employee{
- }
- class Manager extends Employee{ //繼承關係
- }
- Manager m=new Manager();
- Employee e=m; //Manager型別自動轉換為Employee型別
//自動向上轉型
class Employee{
}
class Manager extends Employee{ //繼承關係
}
Manager m=new Manager();
Employee e=m; //Manager型別自動轉換為Employee型別
2、強制型別轉換
在繼承層次中將一個父類的變數轉變成子類型別,必須強制型別轉換。但這種轉換並不是一定成功的:
Java程式碼- //執行失敗
- class Employee{
- }
- class Manager extends Employee{
- }
- Employee e=new Employee(); //e的實際型別為Employee
- Manager m=(Manager)e; //強制轉換為Manager
//執行失敗
class Employee{
}
class Manager extends Employee{
}
Employee e=new Employee(); //e的實際型別為Employee
Manager m=(Manager)e; //強制轉換為Manager
注意:上面的程式碼編譯時可以通過,但執行的時候會產生一個ClassCastException 的非檢查異常。如果不捕獲這個異常,程式將終止。再看一段程式碼:
Java程式碼- //執行成功
- class Employee{
- }
- class Manager extends Employee{
- }
- Employee e=new Manager(); //多型,e的實際型別為Manager
- Manager m=(Manager)e; //強制型別轉換
//執行成功
class Employee{
}
class Manager extends Employee{
}
Employee e=new Manager(); //多型,e的實際型別為Manager
Manager m=(Manager)e; //強制型別轉換
這段程式碼可以正常執行。
如果父類引用的是一個子類的型別(多型情況下)。這是可以通過強制型別轉換把父類變數賦值類子類變數。否則強制型別轉換將以ClassCastException異常結束。
3、instanceof檢查能否成功的向下轉型
在類型別強制轉換的程式設計中,要養成一個良好的習慣:在轉換之前 ,使用instanceof運算子檢視是否能成功轉換。
instanceof運算子用來判斷一個物件是不是某個類或其子類的例項。
Java程式碼- class Employee{
- }
- class Manager extends Employee{
- }
- //e1的引用是Employee型別,e1物件是Employee類的例項,
- Employee e1=new Employee();
- System.out.println("e1:"+e1 instanceof Manager);
- //e2的引用是Employee型別,e2物件是Manager類的例項,
- Employee e2=new Manager();
- System.out.println("e2:"+e2 instanceof Manager);
- //執行結果: e1 : false
- e2 : true
class Employee{
}
class Manager extends Employee{
}
//e1的引用是Employee型別,e1物件是Employee類的例項,
Employee e1=new Employee();
System.out.println("e1:"+e1 instanceof Manager);
//e2的引用是Employee型別,e2物件是Manager類的例項,
Employee e2=new Manager();
System.out.println("e2:"+e2 instanceof Manager);
//執行結果: e1 : false
e2 : true
因此如果instanceof為false的時候,編譯器將不會進行這個轉化
Java程式碼- if(e1 instanceof Manager){
- Manager m=(Manager)e1;
- }
if(e1 instanceof Manager){
Manager m=(Manager)e1;
}
總結:(1) 類型別只能在繼承層次內進行型別轉換
(2) 在向下轉型之前,應該使用instanceof進行檢查