1. 程式人生 > >【解惑】Java型別間的轉型

【解惑】Java型別間的轉型

★ 基本資料型別間的轉換

1、Java要做到平臺無關性,所有的基本資料型別所佔的位元組數量均是固定的。

           boolean ——1/8位元組(1 bit)     byte —— 1位元組             char —— 2位元組         short —— 2位元組

            int —— 4位元組                          long —— 8位元組             float —— 4位元組         double —— 8位元組

2、基本資料型別間的轉換

    (1)  所佔位元組數相對少的基本型別可以自動向位元組數相對多的轉換。

Java程式碼 複製程式碼 收藏程式碼
  1. byte c=(byte)-1//強制轉化為byte型   
  2. int i=c; //自動轉化為整型
  3. 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程式碼 複製程式碼 收藏程式碼
  1. char
     c=(char)-1;   
  2. int i=c; //自動轉化為整型
  3. 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將會被截去。

Java程式碼 複製程式碼 收藏程式碼
  1. int i=10000;  
  2. byte j=(byte)i;  //4位元組強制轉化為1位元組
  3. 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程式碼 複製程式碼 收藏程式碼
  1. //自動向上轉型
  2. class Employee{  
  3. }  
  4. class Manager extends Employee{ //繼承關係
  5. }  
  6. Manager m=new Manager();  
  7. Employee e=m;  //Manager型別自動轉換為Employee型別
//自動向上轉型
class Employee{
}
class Manager extends Employee{ //繼承關係
}

Manager m=new Manager();
Employee e=m;  //Manager型別自動轉換為Employee型別

 2、強制型別轉換

      在繼承層次中將一個父類的變數轉變成子類型別,必須強制型別轉換。但這種轉換並不是一定成功的:

Java程式碼 複製程式碼 收藏程式碼
  1. //執行失敗
  2. class Employee{  
  3. }  
  4. class Manager extends Employee{  
  5. }  
  6. Employee e=new Employee(); //e的實際型別為Employee
  7. Manager m=(Manager)e; //強制轉換為Manager
//執行失敗
class Employee{
}
class Manager extends Employee{
}

Employee e=new Employee(); //e的實際型別為Employee
Manager m=(Manager)e; //強制轉換為Manager

      注意:上面的程式碼編譯時可以通過,但執行的時候會產生一個ClassCastException 的非檢查異常。如果不捕獲這個異常,程式將終止。再看一段程式碼:

Java程式碼 複製程式碼 收藏程式碼
  1. //執行成功
  2. class Employee{  
  3. }  
  4. class Manager extends Employee{  
  5. }  
  6. Employee e=new Manager(); //多型,e的實際型別為Manager
  7. 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程式碼 複製程式碼 收藏程式碼
  1. class Employee{  
  2. }  
  3. class Manager extends Employee{  
  4. }  
  5. //e1的引用是Employee型別,e1物件是Employee類的例項,
  6. Employee e1=new Employee();  
  7. System.out.println("e1:"+e1 instanceof Manager);  
  8. //e2的引用是Employee型別,e2物件是Manager類的例項,
  9. Employee e2=new Manager();  
  10. System.out.println("e2:"+e2 instanceof Manager);  
  11. //執行結果:  e1 : false
  12.                    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程式碼 複製程式碼 收藏程式碼
  1. if(e1 instanceof Manager){  
  2.         Manager m=(Manager)e1;  
  3. }  
if(e1 instanceof Manager){
        Manager m=(Manager)e1;
}

總結:(1) 類型別只能在繼承層次內進行型別轉換

                (2) 在向下轉型之前,應該使用instanceof進行檢查