基本數(shù)據(jù)類型轉(zhuǎn)換
在Java中萍启,我們經(jīng)常使用到基本數(shù)據(jù)的類型轉(zhuǎn)換,類型轉(zhuǎn)換用來將一個數(shù)值從一種類型轉(zhuǎn)換位另一種類型余寥。
我們都直到對于基本數(shù)據(jù)類型怎爵,在內(nèi)存中都會占有不同的大小,如下
數(shù)據(jù)類型 | 位數(shù)(字節(jié)) |
---|---|
char |
16位(2字節(jié)) |
byte |
8位(1字節(jié)) |
short |
16位(2字節(jié)) |
int |
32位(4字節(jié)) |
long |
64位(8字節(jié)) |
float |
32位(4字節(jié)) |
double |
64位(8字節(jié)) |
boolean |
8位(1字節(jié)) |
在基本數(shù)據(jù)的類型轉(zhuǎn)換中分為兩種帅涂,一種是強制(顯式)類型轉(zhuǎn)換议薪,一種是自動(隱式)類型轉(zhuǎn)換。
首先要聲明一下媳友,在Java中所有寫的數(shù)字字面量斯议,對于整數(shù)都是int
類型的,比如:1000
醇锚,這就是一個int
類型的數(shù)字字面量哼御;對于小數(shù)都是double
類型的,比如:2.22
,這就是一個double
類型的數(shù)字字面量焊唬。
強制類型轉(zhuǎn)換指的是數(shù)值范圍較大的數(shù)據(jù)類型變量轉(zhuǎn)換為數(shù)值范圍較小的數(shù)據(jù)類型變量恋昼,這樣有可能會造成精度的損失。這種轉(zhuǎn)換赶促,在編程時需要我們顯示的聲明液肌,例如:
int i = 22;
//對于變量,由于我們有時不能確定變量的具體值鸥滨,所以需要一直進行顯示的聲明類型轉(zhuǎn)換
byte a = (byte)i;
//對于數(shù)字字面量嗦哆,如果其值沒有超出目標數(shù)據(jù)類型的數(shù)值范圍谤祖,則不需要顯示的聲明類型轉(zhuǎn)換
//如果其值超出了目標數(shù)據(jù)類型的數(shù)值范圍,則需要顯示的聲明類型轉(zhuǎn)換老速,這是就會產(chǎn)生精度的損失
byte b = 22;
byte c = (byte)220;
自動類型轉(zhuǎn)換值得是數(shù)值范圍較小的數(shù)據(jù)類型自動轉(zhuǎn)換位數(shù)值范圍較大的數(shù)據(jù)類型粥喜,比如:
byte b = 1;
int i = b;//此時就不需要顯示的聲明類型轉(zhuǎn)換
但是對于從范圍較小的整型類型轉(zhuǎn)換位范圍較大的整型類型時有個規(guī)定:如果最初的值的數(shù)值類型是有符號的,那么就執(zhí)行符號擴展橘券;如果最初的值是char
類型的额湘,那么不管它將要轉(zhuǎn)換成什么類型的數(shù)據(jù),都執(zhí)行零擴展旁舰。那么什么叫符號擴展锋华,什么叫零擴展呢?
符號擴展:二進制中的有符號數(shù)箭窜,符號位總是位于數(shù)的第一位供置,如果向方位較大的數(shù)據(jù)類型進行擴展,符號位也應(yīng)該位于第一位才對绽快,所以當一個負數(shù)被擴展時,其擴展的高位全被置位為1紧阔;對于整數(shù)坊罢,因為符號位是0,所以其擴展的位仍然是0擅耽。
零擴展:不管要轉(zhuǎn)換成什么整型類型活孩,不要最初值的符號位是什么,擴展的高位都被置位0.
下面看這樣一個輸出:
public static void main(String[] args){
System.out.println((int)(char)(byte)-1);
}
也許你會認為不管怎么樣乖仇,該程序都會輸出-1
.當當運行后憾儒,該程序 卻輸出了65535
,這是為什么乃沙?實際上這就關(guān)系到了我們上面提到的符號擴展起趾。
對于字面量-1
,它是一個int類型的數(shù)據(jù)警儒,由于計算機中對于負數(shù)采用二進制補碼來表示训裆,二進制表示為1111 1111 1111 1111 1111 1111 1111 1111
,int
類型轉(zhuǎn)換為byte
類型蜀铲,對數(shù)據(jù)進行窄化边琉,其高24位全部被丟棄,轉(zhuǎn)換后的數(shù)據(jù)仍然是-1
记劝,二進制表示為1111 1111
变姨,這沒有錯。
當byte
類型轉(zhuǎn)換位char
類型時厌丑,是對數(shù)據(jù)進行拓寬數(shù)位定欧,但不可能將一個負byte
值轉(zhuǎn)換為char
類型渔呵。所以實際上從byte
到char
的類型轉(zhuǎn)換時是先將byte
轉(zhuǎn)換為int
類型,然后再將int
類型轉(zhuǎn)換為char
類型忧额。簡單地根據(jù)上面介紹的規(guī)則厘肮,byte
轉(zhuǎn)換為char
發(fā)生符號擴展,拓展的高位全部置為1睦番,char
類型沒有有符號與無符號之分类茂,所以轉(zhuǎn)換后的char
表示的數(shù)據(jù)是65535
。
但是當char
類型轉(zhuǎn)換位int
類型托嚣,從16位拓寬到32位巩检,由于最初數(shù)值是char
類型的,所以不管轉(zhuǎn)換成什么類型的數(shù)據(jù)類型示启,都會執(zhí)行零擴展兢哭,所以轉(zhuǎn)換為作為結(jié)果的int
類型數(shù)據(jù)是65535
。
如果你的程序中運用到了上面的規(guī)則夫嗓,那么你應(yīng)該很清楚地標識出來迟螺。
二進制補碼:計算機中用二進制補碼表示負數(shù),對二進制數(shù)取反舍咖,然后加
1
矩父。比如說-3
,表示位16位二進制,首先將3
表示為二進制0000 0000 0000 0011
排霉,然后對其取反得到1111 1111 1111 1100
窍株,然后在加1,得到1111 1111 1111 1101
表示的-3
的二進制補碼形式.
如果有錯誤的地方攻柠,請指正球订。