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