《Java從小白到大牛》紙質版已經上架了!!!
在聲明變量或常量時會用到數據類型,在前面已經用到一些數據類型,例如int、double和String等。Java語言的數據類型分為:基本類型和引用類型。
5.1 基本數據類型
基本類型表示簡單的數據,基本類型分為4大類,共8種數據類型。
- 整數類型:byte、short、int和long
- 浮點類型:float和double
- 字符類型:char
- 布爾類型:boolean
基本數據類型如圖5-1所示,其中整數類型、浮點類型和字符類型都屬于數值類型,它們之間可以互相轉換。
5.2 整型類型
從圖5-1可見Java中整數類型包括:byte、short、int和long ,它們之間的區別僅僅是寬度和范圍的不同。Java中整數都是有符號,與C不同沒有無符號的整數類型。
Java的數據類型是跨平臺的(與平臺無關),無論你計算機是32位的還是64為的,byte類型整數都是一個字節(8位)。這些整數類型的寬度和范圍如表5-1所示。
表 5-1 整數類型
整數類型 | 寬度 | 取值范圍 |
---|---|---|
byte | 1個字節(8位) | -128~127 |
short | 2個字節(16位) | -215~215-1 |
int | 4個字節(32位) | -231~231-1 |
long | 8個字節(64位) | -263~263-1 |
Java語言的整型類型默認是int類型,例如16表示為int類型常量,而不是short或byte,更不是long,long類型需要在數值后面加l(小寫英文字母)或L(大寫英文字母),示例代碼如下:
public class HelloWorld {
public static void main(String[] args) {
// 聲明整數變量
// 輸出一個默認整數常量
System.out.println("默認整數常量 = " + 16); ①
byte a = 16; ②
short b = 16; ③
int c = 16; ④
long d = 16L; ⑤
long e = 16l; ⑥
System.out.println("byte整數 = " + a);
System.out.println("short整數 = " + b);
System.out.println("int整數 = " + c);
System.out.println("long整數 = " + d);
System.out.println("long整數 = " + e);
}
}
上述代碼多次用到了16整數,但它們是有所區別的。其中代碼①行的16是默認整數類型,即int類型常量。代碼②行16是byte整數類型。代碼③行的16是short類型。代碼第④行的16是int類型。代碼第⑤行的16后加了L,這是說明long類型整數。代碼第⑥行的16后加了l(小寫英文字母l),這是也long類型整數。
提示 在程序代碼中,盡量不用小寫英文字母l,因為它容易與數字1混淆,特別是在Java中表示long類型整數時候很少使用小寫英文字母l,而是使用大寫的英文字母L。例如:16L要比16l可讀性更好。
5.3 浮點類型
浮點類型主要用來儲存小數數值,也可以用來儲存范圍較大的整數。它分為浮點數(float)和雙精度浮點數(double)兩種,雙精度浮點數所使用的內存空間比浮點數多,可表示的數值范圍與精確度也比較大。浮點類型說明如表5-2所示。
表 5-2 浮點類型
浮點類型 | 寬度 |
---|---|
float | 4個字節(32位) |
double | 8個字節(64位) |
Java語言的浮點類型默認是double類型,例如0.0表示double類型常量,而不是float類型。如果想要表示float類型,則需要在數值后面加f或F,示例代碼如下:
public class HelloWorld {
public static void main(String[] args) {
// 聲明浮點數
// 輸出一個默認浮點常量
System.out.println("默認浮點常量 = " + 360.66); ①
float myMoney = 360.66f; ②
double yourMoney = 360.66; ③
final double PI = 3.14159d; ④
System.out.println("float整數 = " + myMoney);
System.out.println("double整數 = " + yourMoney);
System.out.println("PI = " + PI);
}
}
上述代碼①行的360.66是默認浮點類型double。代碼②行360.66f是float浮點類型,float浮點類型常量表示時,數值后面需要加f或F。代碼第③行的360.66表示是double浮點類型。事實上double浮點數值后面也可以加字母d或D,以表示是double浮點數,代碼第④行是聲明一個double類型常量,數值后面加了d字母。
5.4 數字表示方式
整數類型和浮點類型都表示數字類型,那么在給這些類型的變量或常量賦值時,應該如何表示這些數字的值呢?下面介紹一下數字和指數等的表示方式。
5.4.1 進制數字表示
如果為一個整數變量賦值,使用二進制數、八進制數和十六進制數表示,它們的表示方式分別如下:
- 二進制數:以 0b 或0B為前綴,注意0是阿拉伯數字,不要誤認為是英文字母o。
- 八進制數:以0為前綴,注意0是阿拉伯數字。
- 十六進制數:以 0x 或0X為前綴,注意0是阿拉伯數字。
例如下面幾條語句都是表示int整數28。
int decimalInt = 28;
int binaryInt1 = 0b11100;
int binaryInt2 = 0B11100;
int octalInt = 034;
int hexadecimalInt1 = 0x1C;
int hexadecimalInt2 = 0X1C;
5.4.2 指數表示
進行數學計算時往往會用到指數表示的數值。如果采用十進制表示指數,需要使用大寫或小寫的e表示冪,e2表示102。
采用十進制指數表示的浮點數示例如下:
double myMoney = 3.36e2;
double interestRate = 1.56e-2;
其中3.36e2表示的是3.36×102,1.56e-2表示的是1.56×10-2。
5.5 字符類型
字符類型表示單個字符,Java中char聲明字符類型,Java中的字符常量必須用單引號括起來的單個字符,如下所示:
char c = 'A';
Java字符采用雙字節Unicode編碼,占兩個字節(16位),因而可用十六進制(無符號的)編碼形式表示,它們的表現形式是\un,其中n為16位十六進制數,所以'A'字符也可以用Unicode編碼'\u0041'表示,如果對字符編碼感興趣可以到維基百科(https://zh.wikipedia.org/wiki/Unicode字符列表)查詢。
示例代碼如下:
public class HelloWorld {
public static void main(String[] args) {
char c1 = 'A';
char c2 = '\u0041';
char c3 = '花';
System.out.println(c1);
System.out.println(c2);
System.out.println(c3);
}
}
上述代碼變量c1和c2都是保存的'A',所以輸出結果如下:
A
A
花
提示 字符類型也屬于是數值類型,可以與int等數值類型進行數學計算或進行轉換。這是因為字符類型在計算機中保存的是Unicode編碼,雙字節Unicode的存儲范圍在\u0000\uFFFF,所以char類型取值范圍0216-1。
在Java中,為了表示一些特殊字符,前面要加上反斜杠(\),這稱為字符轉義。常見的轉義符的含義參見表5-3。
表 5-3 轉義符
字符表示 | Unicode編碼 | 說 明 |
---|---|---|
\t | \u0009 | 水平制表符tab |
\n | \u000a | 換行 |
\r | \u000d | 回車 |
" | \u0022 | 雙引號 |
' | \u0027 | 單引號 |
\ | \u005c | 反斜線 |
示例如下:
//在Hello和World插入制表符
String specialCharTab1 = "Hello\tWorld.";
//在Hello和World插入制表符,制表符采用Unicode編碼\u0009表示
String specialCharTab2 = "Hello\u0009World.";
//在Hello和World插入換行符
String specialCharNewLine = "Hello\nWorld.";
//在Hello和World插入回車符
String specialCharReturn = "Hello\rWorld.";
//在Hello和World插入雙引號
String specialCharQuotationMark = "Hello\"World\".";
//在Hello和World插入單引號
String specialCharApostrophe = "Hello\'World\'.";
//在Hello和World插入反斜杠
String specialCharReverseSolidus = "Hello\\World.";
System.out.println("水平制表符tab1: " + specialCharTab1);
System.out.println("水平制表符tab2: " + specialCharTab2);
System.out.println("換行: " + specialCharNewLine);
System.out.println("回車: " + specialCharReturn);
System.out.println("雙引號: " + specialCharQuotationMark);
System.out.println("單引號: " + specialCharApostrophe);
System.out.println("反斜杠: " + specialCharReverseSolidus);
輸出結果如下:
水平制表符tab1: Hello World.
水平制表符tab2: Hello World.
換行: Hello
World.
回車: Hello
World.
雙引號: Hello"World".
單引號: Hello'World'.
反斜杠: Hello\World.
5.6 布爾類型
在Java語言中聲明布爾類型的關鍵字是boolean,它只有兩個值:true和false。
提示 在C語言中布爾類型是數值類型,它有兩個取值:1和0。而在Java中的布爾類型取值不能用1和0替代,也不屬于數值類型,不能與int等數值類型之間進行數學計算或類型轉化。
示例代碼如下:
boolean isMan = true;
boolean isWoman = false;
如果試圖給它們賦值true和false之外的常量,如下所示。
boolean isMan = 1;
boolean isWoman = 'A';
則發生類型不匹配編譯錯誤。
5.7 數值類型相互轉換
學習了前面的數據類型后,大家會思考一個問題,數據類型之間是否可以轉換呢?數據類型的轉換情況比較復雜。基本數據類型中數值類型之間可以互相轉換,布爾類型不能與它們之間進行轉換。但有些不兼容類型之間,如String(字符串)轉換為int整數等,可以借助于一些類的方法實現。本節只討論數值類型的互相轉換。
從圖5-1可見數值類型包括了byte、short、char、int、long、float和double,這些數值類型之間的轉換有兩個方向:自動類型轉換和強制類型轉換。
5.7.1 自動類型轉換
自動類型轉換就是需要類型之間轉換是自動的,不需要采取其他手段,總的原則是小范圍數據類型可以自動轉換為大范圍數據類型,列類型轉換順序如圖5-2所示,從左到右是自動。
注意 如圖5-2所示,char類型比較特殊,char自動轉換為int、long、float和double,但byte和short不能自動轉換為char,而且char也不能自動轉換為byte或short。
自動類型轉換不僅發生在賦值過程中,在進行數學計算時也會發生自動類型轉換,在運算中往往是先將數據類型轉換為同一類型,然后在進行計算。計算規則如表5-4所示。
表5-4 計算過程中自動類型轉換規則
操作數1類型 | 操作數2類型 | 轉換后的類型 |
---|---|---|
byte、short、char | int | int |
byte、short、char、int | long | long |
byte、short、char、int、long | float | float |
byte、short、char、int、long、float | double | double |
示例如下:
// 聲明整數變量
byte byteNum = 16;
short shortNum = 16;
int intNum = 16;
long longNum = 16L;
// byte類型轉換為int類型
intNum = byteNum;
// 聲明char變量
char charNum = '花';
// char類型轉換為int類型
intNum = charNum;
// 聲明浮點變量
// long類型轉換為float類型
float floatNum = longNum;
// float類型轉換為double類型
double doubleNum = floatNum;
//表達式計算后類型是double
double result = floatNum * intNum + doubleNum / shortNum; ①
上述代碼第①行中表達式loatNum * intNum + doubleNum / shortNum進行數學計算,該表達式是由4個完全不同的數據類型組成,范圍最大的是double,所以在計算過程中它們先轉換成double,所以最后的結果是double。
5.7.2 強制類型轉換
在數值類型轉換過程中,除了需要自動類型轉換外,有時還需要強制類型轉換,強制類型轉換是在變量或常量之前加上“(目標類型)”實現,示例代碼如下:
//int型變量
int i = 10;
//把int變量i強制轉換為byte
byte b = (byte) i;
上述代碼(byte) i表達式實現強制類型轉換。強制類型轉換主要用于大寬度類型轉換為小寬度類型情況,如把int轉換為byte。示例代碼如下:
//int型變量
int i = 10;
//把int變量i強制轉換為byte
byte b = (byte) i;
int i2 = (int)i; ①
int i3 = (int)b; ②
上述代碼第①行是將int類型的i變量“強制類型轉換”為int類型,這顯然是沒有必要,但是語法也是允許的。代碼第②行是將byte類型的b變量強制轉換為int類型,從圖5-2可見這個轉換是自動,不需要強制轉換,本例中這個轉換沒有實際意義,但有時為了提高精度需要種轉換。示例代碼如下:
//int型變量
int i = 10;
float c1 = i / 3; ①
System.out.println(c1); ②
//把int變量i強制轉換為float
float c2 = (float)i / 3; ③
System.out.println(c2); ④
輸出結果:
3.0
3.3333333
上述代碼比較輸出結果發現c1和c2變量小數部分差別比較大的,這種差別在一些金融系統中是不允許的。在代碼第①行i除以3從結果是小數,但由于兩個操作數都是整數int類型,小數部分被截掉了,結果是3,然后再賦值給float 類型的c1變量,最后c1保持的是3.0。為了防止兩個整數進行除法等運算導致小數位被截掉問題,可以將其中一個操作數強制類型轉換為float,見代碼第③行,這樣計算過程中操作數是float類型,結果也是float不會截掉小數部分。
再看一個強制類型轉換與精度丟失的示例。
long yourNumber = 6666666666L;
System.out.println(yourNumber);
int myNuber = (int)yourNumber;
System.out.println(myNuber);
輸出結果:
6666666666
-1923267926
上述代碼輸出結果可見,經過強制類型轉換后,原本的6666666666L變成了負數。當大寬度數值轉換為小寬度數值時,大寬度數值的高位被截掉,這樣就會導致數據精度丟失。除非大寬度數值的高位沒有數據,就是這個數比較小的情況,例如將6666666666L換為6L就不會丟失精度。
5.8 引用數據類型
在Java中除了8種基本數據類型外,其他數據類型全部都是引用(reference)數據類型,引用數據類型用了表示復雜數據類型,如圖5-3所示,包含:類、接口和數組聲明的數據類型。
提示 Java中的引用類型,相當于C等語言中指針(pointer)類型,引用事實上就是指針,是指向一個對象的內存地址。引用類型變量中保持的是指向對象的內存地址。很多資料上提到Java不支持指針,事實上是不支持指針計算,而指針類型還是保留了下來,只是在Java中稱為引用類型。
引用數據類型示例如下:
int x = 7; ①
int y = x; ②
String str1 = "Hello"; ③
String str2 = str1; ④
str2 = "World"; ⑤
上述代碼聲明了兩個基本數據類型(int)和兩個引用數據類型(String)。當程序執行完第②行代碼后,x值為7,x賦值給y,這時y的值也是7,它們的保持方式如圖5-4所示,x和y兩個變量值都是7,但是它們之間是獨立的,任何一個變化都不會影響另一個。
當程序執行完第③行時,字符串“Hello”對象被創建,保持到內存地址0x12345678中,str1是引用類型變量,它保存的是內存地址0x12345678,這個地址指向“Hello”對象。
當程序執行完第④行時,str1變量內容(0x12345678)被賦值給str2是引用類型變量,這樣一來str1和str2保存了相同的內存地址,都指向“Hello”對象。見圖5-4所示,此時str1和str2本質上是引用一個對象,通過任何一個引用都可以修改對象本身。
當程序執行完第⑤行時,字符串“World”對象被創建,保持到內存地址0x23455678中,地址保存到str2變量中,此時,str1和str2不再指向相同內存地址,見圖5-5所示。
本章小結
本章主要介紹了Java中的數據類型,讀者需要重點掌握基本數據類型,理解基本數據類型與引用數據類型的區別,熟悉數值類型如何互相轉換。
配套視頻
http://www.zhijieketang.com/classroom/6/courses
配套源代碼
http://www.zhijieketang.com/group/5