整數(shù)型數(shù)據(jù)在java中有三種表示方式,分別是十進(jìn)制、八進(jìn)制、十六進(jìn)制。默認(rèn)為十進(jìn)制,以0開(kāi)始表示八進(jìn)制,以0x開(kāi)始表示十六進(jìn)制。
● 十進(jìn)制:0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17...
● 八進(jìn)制:0,1,2,3,4,5,6,7,10,11,12,13,14,15,16,17,20,21...
● 十六進(jìn)制:0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f,10,11...
在java語(yǔ)言當(dāng)中,整數(shù)型字面量被當(dāng)做int類型處理,如果想表示long類型則需要在字面量后面添加L/l,建議大寫(xiě)L,因?yàn)樾?xiě)l和1不好區(qū)分。請(qǐng)看以下程序:
public class IntegerTypeTest01 {
public static void main(String[] args) {
//十進(jìn)制
int a = 10;
System.out.println("a = " + a);
//八進(jìn)制
int b = 010;
System.out.println("b = " + b);
//十六進(jìn)制
int c = 0x10;
System.out.println("c = " + c);
}
}
運(yùn)行結(jié)果如下圖所示:
圖4-5:十、八、十六進(jìn)制
接下來(lái)繼續(xù)看以下代碼:
public class IntegerTypeTest02 {
public static void main(String[] args) {
//聲明一個(gè)int類型的變量a
//100被默認(rèn)當(dāng)做int類型處理
//以下代碼不存在類型轉(zhuǎn)換
int a = 100;
//100被默認(rèn)當(dāng)做int類型處理,占用4個(gè)字節(jié)
//b變量是long類型,默認(rèn)可容納8個(gè)字節(jié)
//小容量轉(zhuǎn)換成大容量,叫做自動(dòng)類型轉(zhuǎn)換
long b = 100;
//b變量long類型,占用8個(gè)字節(jié)
//c變量int類型,占用4個(gè)字節(jié)
//大容量不能直接賦值給小容量,編譯報(bào)錯(cuò)了
//int c = b;
//強(qiáng)制類型轉(zhuǎn)換需要添加強(qiáng)制類型轉(zhuǎn)換符
//強(qiáng)制類型轉(zhuǎn)換時(shí)可能引起精度損失,謹(jǐn)慎使用
int c = (int)b;
//a是int類型
//b是long類型
//c是int類型
//多種數(shù)據(jù)類型混合運(yùn)算時(shí)先轉(zhuǎn)換成容量最大的再做運(yùn)算
//最終的結(jié)果是long類型,大容量無(wú)法直接賦值給小容量
//所以編譯報(bào)錯(cuò)了
//int d = a + b + c;
//解決以上編譯錯(cuò)誤
int d = (int)(a + b + c);
System.out.println("d = " + d);
//或者
long d2 = a + b + c;
System.out.println("d2 = " + d2);
//100L被當(dāng)做long類型處理
//x變量是long類型
//不存在類型轉(zhuǎn)換
long x = 100L;
System.out.println("x = " + x);
}
}
運(yùn)行結(jié)果如下圖所示:
圖4-6:整數(shù)型測(cè)試
通過(guò)以上代碼的學(xué)習(xí),我們知道小容量轉(zhuǎn)換成大容量叫做自動(dòng)類型轉(zhuǎn)換,大容量轉(zhuǎn)換成小容量叫做強(qiáng)制類型轉(zhuǎn)換,強(qiáng)制類型轉(zhuǎn)換要想編譯通過(guò)必須添加強(qiáng)制類型轉(zhuǎn)換符,雖然編譯通過(guò)了,但運(yùn)行階段可能出現(xiàn)精度損失,謹(jǐn)慎使用。
接下來(lái)我們一起來(lái)看看精度損失的情況:
運(yùn)行結(jié)果如下圖所示:
圖4-7:精度損失
4個(gè)字節(jié)的int類型300強(qiáng)轉(zhuǎn)為1個(gè)字節(jié)的byte類型,最終的結(jié)果是44,為什么呢?首先300對(duì)應(yīng)的二進(jìn)制碼是:00000000 00000000 00000001 00101100,強(qiáng)制類型轉(zhuǎn)換的時(shí)候會(huì)變成1個(gè)字節(jié),這個(gè)時(shí)候底層是將前3個(gè)字節(jié)砍掉了,也就是最后的二進(jìn)制碼是:00101100,這個(gè)二進(jìn)制碼對(duì)應(yīng)的是44。
接下來(lái)我們?cè)賮?lái)看一下如果精度損失之后成為負(fù)數(shù)的情況:
public class IntegerTypeTest03 {
public static void main(String[] args) {
int a = 300;
byte b = (byte)a;
System.out.println("b = " + b);
}
}
運(yùn)行結(jié)果如下圖所示:
圖4-8:精度損失
為什么以上的運(yùn)行結(jié)果是-106呢?那是因?yàn)橛?jì)算機(jī)在任何情況下都是采用二進(jìn)制補(bǔ)碼的形式存儲(chǔ)數(shù)據(jù)的(至于為什么采用二進(jìn)制補(bǔ)碼形式存儲(chǔ)數(shù)據(jù),這里就不再贅述了,畢竟我們不是做學(xué)術(shù)研究)。
計(jì)算機(jī)二進(jìn)制編碼方式包括原碼、反碼、補(bǔ)碼。對(duì)于正數(shù)來(lái)說(shuō)原碼、反碼、補(bǔ)碼是同一個(gè)。對(duì)于負(fù)數(shù)來(lái)說(shuō)呢?負(fù)數(shù)的反碼是在其原碼的基礎(chǔ)上, 符號(hào)位不變,其余各個(gè)位取反,例如:-15的原碼是:10001111,-15反碼是:11110000。負(fù)數(shù)的補(bǔ)碼是其反碼再加1。例如:-15的補(bǔ)碼是11110000加1:11110001。換句話說(shuō)-15最終在計(jì)算機(jī)上會(huì)采用11110001二進(jìn)制來(lái)表示。
我們?cè)賮?lái)看看以上的程序:int a = 150。4個(gè)字節(jié)的150對(duì)應(yīng)的二進(jìn)制是:00000000 00000000 00000000 10010110,強(qiáng)轉(zhuǎn)時(shí)前3個(gè)字節(jié)砍掉,最終計(jì)算機(jī)存儲(chǔ)的二進(jìn)制為:10010110,我們之前說(shuō)過(guò)最終存儲(chǔ)在計(jì)算機(jī)中的是二進(jìn)制補(bǔ)碼形式,也就是說(shuō)10010110現(xiàn)在是二進(jìn)制補(bǔ)碼形式,我們通過(guò)補(bǔ)碼推出原碼,負(fù)數(shù)的補(bǔ)碼是反碼+1,所以10010110減1就是反碼10010101,反碼的符號(hào)位不變,其余位取反就能得出原碼:11101010,而這個(gè)值就是-106。
接下來(lái)我們?cè)賮?lái)看一段程序,分析以下程序錯(cuò)在哪里,為什么以及怎么解決?
public class IntegerTypeTest05 {
public static void main(String[] args) {
long num = 2147483648;
}
}
編譯報(bào)錯(cuò)了:
圖4-9:編譯錯(cuò)誤提示信息
以上程序編譯報(bào)錯(cuò)的原因是:java程序見(jiàn)到2147483648這個(gè)整數(shù)的時(shí)候,默認(rèn)將其當(dāng)做int類型來(lái)處理,但這個(gè)數(shù)字本身已經(jīng)超出了int類型的取值范圍,所以編譯報(bào)錯(cuò)了,注意:這里編譯報(bào)錯(cuò)的原因并不是說(shuō)long類型存不下,long類型的變量完全可以存儲(chǔ)這個(gè)數(shù)字,以上程序出現(xiàn)的錯(cuò)誤是在賦值之前,還沒(méi)有進(jìn)行到賦值運(yùn)算,數(shù)字本身已經(jīng)超出int類型范圍,自己崩掉了。怎么解決以上的問(wèn)題呢?其實(shí)很簡(jiǎn)單,我們只要讓java程序認(rèn)為2147483648是一個(gè)long類型的數(shù)據(jù)就行了,也就是說(shuō)在該數(shù)字后面添加L問(wèn)題就解決了(long num = 2147483648L;)。
再來(lái)看一看整數(shù)類型還有沒(méi)有其它的知識(shí)點(diǎn)要學(xué)習(xí),請(qǐng)看以下程序:
public class IntegerTypeTest06 {
public static void main(String[] args) {
byte b = 127;
short s = 32767;
char c = 65535;
byte b1 = 128;
short s1 = 32768;
char c1 = 65536;
}
}
編譯報(bào)錯(cuò)了:
圖4-10:編譯錯(cuò)誤提示信息
通過(guò)以上測(cè)試,大家需要記住一個(gè)結(jié)論:當(dāng)一個(gè)整數(shù)型的字面量沒(méi)有超出byte,short,char的取值范圍,可以將該字面量直接賦值給byte,short,char類型的變量。