要說類型轉換,首先要說一說java的數據類型。java中的數據類型分為兩種:基本類型、引用類型。基本數據類型沒有什麼好說的byte char short int long float double boolean,這些類型除了boolean之外,其他的與C語言中的類型沒有太大的區別。因為這篇文章的論題是類型轉換,所以在此不討論boolean值的用法。
下面要說的是引用類型。引用在有的書裡也叫做句柄,它很類似C/C++中的指針,但要注意引用和指針並不是同一個概念。指針是一個存放地址的變量,他使C/C++程序員能夠靈活地訪問內存,但這也給程序的安全性帶來了很大的隱患,由於程序員可以對指針隨意的運算操作,所以一不留神就會破壞其他的存儲單位,導致程序中出現意想不到的結果。引用繼承了指針節省內存的優點,又限制了對地址的操作,所以他是安全的。引用類型包括所有類生成的實例和數組(不管是對象數組還是基本類型數組都實現Cloneable接口,所以他也是一個對象實例),所有引用類型都繼承自Object這個類。要說明一點的是java中的所有變量都是一個引用,不管是引用類型還是基本類型。
現在要正式討論類型的轉換了。用過C/C++的人對基本類型的轉換都會很清楚,基本類型轉換分為類型提升和強制轉換。
例如:
int a=100;
long b=a+100;//這個地方就用到了類型提升,a+100從int提升到了long
a=(int)b;//這個地方用到了強制轉換
強制類型轉換在某種情況下會丟失精度,如:
byte b;
int a=200;
b=(byte)a;//雖然這裡用到了強制轉換,但因為byte的范圍是-127到127
//所以強制轉換後寬度會被截短
在java中除了這些轉換之外基本數據類型還可以被隱式的轉換成String,例如:
System.out.print("轉換"+100);//如果在數據前面有字符串用+連接
//就會隱式的轉換成String
引用類型的轉換實現起來要比C++簡單的多,如果一個對象與另一個對象沒有任何的繼承關系,那麼他們就不能進行類型轉換。如果要把一個派生類對象賦值給基類對象這個稱為上溯造型。如果要把基類對象賦值給派生類對象就需要強制類型轉換,這稱為下溯造型,下溯造型有一些危險,要安全的進行下溯造型有一個前題,基類對象必須是從派生類對象中上溯過來的。
例如:
class Base{}
class Child extends Base{
public static void main(String[] args){
Base base=new Child();//上溯造型
Child child=(Child)base;//下溯造型
Child child1=(Child)new
Base();//拋出ClassCastException異常
}
}
最後,談一談String與引用類型的轉換。前面已經說過,所有的對象都是從Object繼承過來的,Object中有一個toString方法。這個方法是所有的對象都可以轉換成String,如果想把自定義的類轉換成String,最安全的做法是重寫toString方法。和基本類型一樣如果對象前有String對象用+連接,對象就會隱式轉換成String,這種情況實際上是隱式調用了toString方法。