- Java從入門到精通(第2版)
- 龍馬高新教育策劃 魔樂科技(MLDN)軟件實(shí)訓(xùn)中心編著 張玉宏主編
- 528字
- 2019-01-02 04:58:51
第5章 不可不知的數(shù)據(jù)分類法—數(shù)據(jù)類型
本章視頻教學(xué)錄像:1 小時(shí)46分鐘
Java的數(shù)據(jù)類型在程序語言的構(gòu)成要素里占有相當(dāng)重要的地位。Java的數(shù)據(jù)類型可分為基本數(shù)據(jù)類型與引用數(shù)據(jù)類型兩大類。本章介紹Java的基本數(shù)據(jù)類型和數(shù)據(jù)類型的轉(zhuǎn)換,其中重點(diǎn)講述整型、浮點(diǎn)類型、字符類型和布爾類型。最后對基本數(shù)據(jù)類型的默認(rèn)值進(jìn)行討論。
本章要點(diǎn)(已掌握的在方框中打鉤)
□ 掌握整數(shù)類型的分類
□ 掌握浮點(diǎn)數(shù)據(jù)類型的分類
□ 掌握字符類型數(shù)據(jù)
□ 掌握布爾類型數(shù)據(jù)
□ 熟悉基本數(shù)據(jù)類型默認(rèn)值的意義與使用方法
5.1 數(shù)據(jù)類型的意義
本節(jié)視頻教學(xué)錄像:41分鐘
為什么要有數(shù)據(jù)類型?在回答這個(gè)問題之前,我們先溫習(xí)下先賢孔子在《論語·陽貨》里的一句話:“子之武城,聞弦歌之聲。夫子莞爾而笑,曰:‘割雞焉用牛刀。’”
據(jù)此,衍生了中國一個(gè)著名的成語——“殺雞焉用宰牛刀”?這是疑問句式。是的,殺雞的刀用來殺雞,宰牛的刀用來宰牛,用宰牛的刀殺雞,豈不大材小用?
殺雞的刀和宰牛的刀雖然都是刀,但屬于不同的類型,如果二者混用,要么出現(xiàn)“大材小用”,要么出現(xiàn)“不堪使用”的情況。由此,可以看出,正是有了類型的區(qū)分,我們才可以根據(jù)不同的類型,確定其不同的功能,然后“各司其職”,不出差錯(cuò)。

除了不同類型的“刀”承擔(dān)的功能不一樣,而且如果我們給“殺雞刀”和“宰牛刀”各配一個(gè)刀套,刀套的大小也自然是不同的。“殺雞刀”放到“宰牛刀”的刀套里,勢必空間浪費(fèi),而“宰牛刀”“放到殺雞刀”的刀套里,勢必放不下。在必要時(shí),“宰牛刀”“經(jīng)過打磨,可以做成“殺雞刀”。
從哲學(xué)上來看,很多事物的表象千變?nèi)f化,而其本質(zhì)卻是相同。類似的,在Java語言中,每個(gè)變量(常量)都有其數(shù)據(jù)類型。不同的數(shù)據(jù)類型可允許的操作也是不同的。比如,對于整型數(shù)據(jù),它們只能進(jìn)行加減乘除和求余操作。此外,不同的數(shù)據(jù)占據(jù)的內(nèi)存空間大小也是不盡相同的。而在必要時(shí),不同的數(shù)據(jù)類型也是可以做到強(qiáng)制類型轉(zhuǎn)換的。
程序,本質(zhì)上就是針對數(shù)據(jù)的一種處理流程。那么,針對程序所能夠處理的數(shù)據(jù),就是程序語言的各個(gè)數(shù)據(jù)類型劃分。正是有了各種數(shù)據(jù)類型,程序才可以“有的放矢”進(jìn)行各種不同數(shù)據(jù)操作。
在Java之中數(shù)據(jù)類型一共分為兩大類:基本數(shù)據(jù)類型、引用數(shù)據(jù)類型。由于引用數(shù)據(jù)類型較為難理解,所以針對于此部分的內(nèi)容,本章暫不作討論,本章討論的是基本數(shù)據(jù)類型。在Java中規(guī)定了8種基本數(shù)據(jù)類型變量來存儲(chǔ)整數(shù)、浮點(diǎn)數(shù)、字符和布爾值,如下圖所示。

一個(gè)變量就如同一個(gè)杯子或一個(gè)容器,在其內(nèi)要裝載某個(gè)特定的數(shù)值(如同杯子里可盛水或咖啡等)。杯子有大有小,杯子里裝的水(咖啡)也有多有少。同樣,不同類型的變量,其能表示的數(shù)據(jù)范圍也是不同的。Java的基本數(shù)據(jù)類型占用內(nèi)存位數(shù)及可表示的數(shù)據(jù)范圍如下表所示。

5.2 整數(shù)類型
本節(jié)視頻教學(xué)錄像:20分鐘
整數(shù)類型(Integer),簡稱整型,表示的是不帶有小數(shù)點(diǎn)的數(shù)字。例如,數(shù)字10、20就表示一個(gè)整型數(shù)據(jù)。在Java中,有4種不同類型的整型,按照占據(jù)空間大小的遞增次序,分別為byte(位)、short(短整型)、int(整數(shù))及l(fā)ong(長整數(shù))。在默認(rèn)情況下,整數(shù)類型是指int型,那么下面先通過代碼來觀察一下。
舉例來說,想聲明一個(gè)短整型變量sum時(shí),可以在程序中做出如下的聲明。
short sum; //聲明sum為短整型
經(jīng)過聲明之后,Java即會(huì)在可使用的內(nèi)存空間中,尋找一個(gè)占有2個(gè)字節(jié)的塊供sum變量使用,同時(shí)這個(gè)變量的范圍只能在-32768 到 32767之間。
5.2.1 byte類型
在Java中,byte類型占據(jù)1字節(jié)內(nèi)存空間,數(shù)據(jù)的取值范圍為-128 ~ 127。
【范例5-1】 byte類型數(shù)據(jù)的使用(代碼bytedemo.java)。
01 public class bytedemo
02 { 03 public static void main(String args[]) 04 { 05 byte byte_max=Byte.MAX_VALUE;//得到Byte型的最大值 06 07 System.out.println("BYTE的最大值:"+byte_max); 08 } 09 }
【運(yùn)行結(jié)果】
程序運(yùn)行結(jié)果如下圖所示。
【范例分析】

每種基本的數(shù)據(jù)類型都有幾個(gè)靜態(tài)屬性,如MAX_VALUE(最大值)、MIN_VALUE(最小值)、SIZE(大小)、TYPE(類型)等。要得到這些值,可用名稱為該類型首字母大小對象(如byte類型對應(yīng)Byte對象)通過點(diǎn)(.)操作符將其讀取出來,參見代碼05行。Byte 類將基本類型 byte 的值包裝在一個(gè)對象中。一個(gè) Byte 類型的對象只包含一個(gè)類型為 byte 的字段。Byte類常見的靜態(tài)屬性如下表所示。
屬性名稱
MAX VALUE
MIN VALUE
SIZE
TYPE
屬性值
最大值:27-1=127
最小值:-27=-128
所占的內(nèi)存位數(shù)(bit):8位
數(shù)據(jù)類型:byte
5.2.2 short類型
short類型數(shù)據(jù)占據(jù)2個(gè)字節(jié)內(nèi)存空間,取值范圍為-32768 ~ 32767。
【范例5-2】 short類型數(shù)據(jù)的使用(代碼shortdemo.java)。
01 public class shortdemo 02 { 03 public static void main(String args[])
04 { 05 short short_max=Short.MAX_VALUE; //得到短整型的最大值 06 07 System.out.println("SHORT的最大值:"+short_max); 08 09 } 10 }
【運(yùn)行結(jié)果】
程序運(yùn)行結(jié)果如下圖所示。

【范例分析】
代碼05行的功能就是獲得短整數(shù)所能表達(dá)的最大數(shù)值(Short.MAX_VALUE)。
5.2.3 int類型
int類型數(shù)據(jù)占據(jù)4個(gè)字節(jié)內(nèi)存空間,取值范圍為-2147483648 ~ 2147483647。
【范例5-3】 int類型數(shù)據(jù)的使用(intdemo.java)。
01 public class intdemo 02 { 03 public static void main(String args[]) 04 { 05 int int_max= java.lang.Integer.MAX_VALUE ; //得到整型的最大值 06 //int int_max= Integer.MAX_VALUE ; //與上一句功能相同 07 System.out.println("INT的最大值:"+int_max); 08 09 } 10 }
【運(yùn)行結(jié)果】
程序運(yùn)行結(jié)果如下圖所示。

【范例分析】
代碼05行的功能就是獲得短整型所能表達(dá)的最大數(shù)值(Integer.MAX_VALUE)。由于java.lang包是Java語言默認(rèn)加載的,所以第05行的語句可以簡化為被注釋的第06行。lang是language(語言)的簡寫。范例【5-1】和范例【5-2】使用的就是這種簡寫模式。
由于每一種類型畢竟都有其對應(yīng)范圍的最大或最小值,那么如果說在計(jì)算的過程之中,超過了此范圍(大于最大值或小于最小值),那么就會(huì)產(chǎn)生數(shù)據(jù)的溢出問題。請參見如下的范例,整型數(shù)據(jù)的溢出(ShotDemo2.java)。
01 public class ShotDemo2 02 { 03 public static void main(String args[]) 04 { 05 int max=Integer.MAX_VALUE; //取得int的最大值 06 int min=Integer.MIN_VALUE; //取得int的最小值 07 System.out.println(max); //最大值:2147483647 08 System.out.println(min); //最小值:-2147483648 09 System.out.println(max+1); //得到最小值:-2147483648 10 System.out.println(max+2); //相當(dāng)于最小值+1:-2147483647 11 System.out.println(min-1); //得到最大值:2147483647 12 } 13 }
【運(yùn)行結(jié)果】
運(yùn)行結(jié)果如下圖所示。

【范例分析】
第07、08行分別輸出int類型的最大值和最小值。那么比int類型的最大值還大1是什么值?比int類型的最小值還小1的是什么值?第09行和第11行分別給出了答案,比int類型的最大值還大1是最小值,而int類型的最小值還小1的是最大值。這里的最大值、最小值的轉(zhuǎn)換是不是有點(diǎn)中國哲學(xué)里“物極必反,否極泰來”的味道呢?悟到這個(gè)道理,讀者朋友才能找出實(shí)戰(zhàn)練習(xí)(5.9節(jié)中)第2題中的錯(cuò)誤。數(shù)據(jù)最大值、最小值會(huì)出現(xiàn)一個(gè)循環(huán)過程,這種情況就稱為數(shù)據(jù)溢出(overflow)。
5.2.4 long類型
long類型數(shù)據(jù)占據(jù)8個(gè)字節(jié)內(nèi)存空間,取值范圍為-9223372036854775808 ~ 9223372036854775807。
【范例5-4】 long類型數(shù)據(jù)的使用(LongDemo.java)。
01 public class LongDemo 02 { 03 public static void main(String args[]) 04 { 05 long long_max=java.lang.Long.MAX_VALUE; //得到長整型的最大值 06 System.out.println("LONG的最大值:"+long_max); 07 } 08 }
【運(yùn)行結(jié)果】
程序運(yùn)行結(jié)果如下圖所示。

【范例分析】
范例第05行定義長整型long_max,并將系統(tǒng)定義好的java.lang.Long.MAX_VALUE賦給這個(gè)變量。第07行輸出這個(gè)值。
在范例【5-4】中,我們演示了整型數(shù)據(jù)的數(shù)據(jù)溢出問題,而要想解決數(shù)據(jù)的溢出問題,那么最好的做法是擴(kuò)大數(shù)據(jù)的操作范圍,比int范圍大的是剛剛講到的long類型,所以可將其擴(kuò)充為long,有兩種方式擴(kuò)充。
⑴ 直接在數(shù)據(jù)前增加一個(gè)“(long)”;
⑵ 直接在數(shù)據(jù)后增加一個(gè)字母“L”。
具體用法參見【范例5-5】所示。
【范例5-5】 使用long類型解決int類型溢出問題(LongDemo.java)。
01 public class intOverflowToLong 02 {
03 public static void main(String args[]) 04 { 05 int max=Integer.MAX_VALUE; //取得int的最大值 06 int min=Integer.MIN_VALUE; //取得int的最小值 07 System.out.println(max); //最大值:2147483647 08 System.out.println(min); //最小值:-2147483648 09 System.out.println(max+(long)1); //int型+long型=long型,2147483648 10 System.out.println(max+2L); //int型+long型=long型,2147483649 11 System.out.println(min-1L); //int型-long型=long型,-2147483649 12 } 13 }
【運(yùn)行結(jié)果】
運(yùn)行結(jié)果如下圖所示。

【范例分析】
第09行,數(shù)字1前面的long表示把1強(qiáng)制轉(zhuǎn)換為長整型(默認(rèn)情況下1為普通整型int),為了不丟失數(shù)據(jù)的精度,低字節(jié)類型數(shù)據(jù)與高字節(jié)數(shù)據(jù)運(yùn)算,其結(jié)果自動(dòng)轉(zhuǎn)變?yōu)楦咦止?jié)數(shù)據(jù),因此,int型與long型運(yùn)算的結(jié)果是 long型數(shù)據(jù)。
第10行和第11行,整型數(shù)據(jù)2和1后的字母“L”也達(dá)到把2和1轉(zhuǎn)變?yōu)殚L整型的效果。
請讀者對照對比體會(huì)范例【5-4】和范例【5-5】的區(qū)別。類型轉(zhuǎn)換的知識(shí)將在5.6節(jié)詳述。
5.3 浮點(diǎn)類型
本節(jié)視頻教學(xué)錄像:10分鐘
Java浮點(diǎn)數(shù)據(jù)類型主要有雙精度double和單精度float兩個(gè)類型。
double類型:共8個(gè)字節(jié),64位,第1位為符號(hào)位,中間11位表示指數(shù),最后52位為尾數(shù)。float類型:共4個(gè)字節(jié),32位,第1位為符號(hào)位,中間8位表示指數(shù),最后23位表示尾數(shù)。
5.3.1 float類型
下面舉一個(gè)簡單的例子。在程序中,聲明一個(gè)float類型的變量num,并賦值為3.0,將num*num的運(yùn)算結(jié)構(gòu)輸出到顯示器上。
【范例5-6】 浮點(diǎn)類型的使用(floatDemo.java)。
01 //下面這段程序說明了浮點(diǎn)數(shù)類型的使用方法 02 public class floatDemo 03 { 04 public static void main(String args[]) 05 { 06 float num=3.0f; 07 System.out.println(num+"*"+num+"="+(num*num)); 08 } 09 }
【運(yùn)行結(jié)果】
程序運(yùn)行結(jié)果如下圖所示。

【范例分析】
需要注意一點(diǎn),含小數(shù)的實(shí)數(shù)默認(rèn)為double類型數(shù)據(jù),如果定義的是float型數(shù)據(jù),為其賦值的時(shí)候,必須要執(zhí)行強(qiáng)制轉(zhuǎn)型,有兩種方式。
⑴ 直接加上字母“F”,或小寫字母“f”,例如:“float data = 1.2F ;”或“float data = 1.2f”。
⑵ 直接在數(shù)字前加強(qiáng)制轉(zhuǎn)型為“float”,例如:“float data2 = (float) 1.2 ;”。
范例中06行定義了一個(gè)float類型變量num,并賦值為3.0f。其中3.0后的字母“f”其實(shí)就是上面講到的第一種強(qiáng)制類型轉(zhuǎn)換。07行將num做了簡單的乘法運(yùn)算輸出。
5.3.2 double類型
當(dāng)浮點(diǎn)數(shù)的表示范圍不夠大的時(shí)候,還有一種雙精度(double)浮點(diǎn)數(shù)可供使用。雙精度浮點(diǎn)數(shù)類型的長度為64個(gè)字節(jié),有效范圍為-1.7×10308~1.7×10308。
Java提供了浮點(diǎn)數(shù)類型的最大值與最小值的代碼,其所使用的類全名與所代表的值的范圍,可以在下表中查閱。

類似的,在類全名中,可以省去類庫java.lang,直接取用類名稱即可。下面的程序是輸出float與double兩種浮點(diǎn)數(shù)類型的最大與最小值,讀者可以將下面程序的輸出結(jié)果與上表一一進(jìn)行比較。
【范例5-7】 取得單精度和雙精度浮點(diǎn)數(shù)類型的最大、最小值(doubleAndFloatDemo. java)。
01 //下面這段程序用于取得單精度和雙精度浮點(diǎn)數(shù)類型的最大、最小值 02 public class doubleAndFloatDemo 03 { 04 public static void main(String args[]) 05 { 06 System.out.println("float_max="+java.lang.Float.MAX_VALUE); 07 System.out.println("float_min="+java.lang.Float.MIN_VALUE); 08 System.out.println("double_max="+java.lang.Double.MAX_VALUE); 09 System.out.println("double_min="+java.lang.Double.MIN_VALUE); 10 } 11 }
【運(yùn)行結(jié)果】
程序運(yùn)行結(jié)果如下圖所示。

下面為聲明與設(shè)置float與double類型的變量時(shí)應(yīng)注意的事項(xiàng)。
double num1=-6.3e64; //聲明num1為double,其值為-6.3*10^64 double num2=-5.34E16; //e也可以用大寫的E來取代
float num3=7.32f; //聲明num3為float,并設(shè)初值為7.32f float num4=2.456E67; //錯(cuò)誤,因?yàn)?.456*1067已超過float可表示的范圍
5.4 字符類型(char)
本節(jié)視頻教學(xué)錄像:11分鐘
字符,顧名思義,就是字母和符號(hào)的統(tǒng)稱。字符類型在內(nèi)存中占有2個(gè)字節(jié),定義時(shí)語法為。
char a=‘字’; //聲明a為字符型,并賦初值為‘字’
下面給出一個(gè)范例來說明它的用法。
【范例5-8】 直接給字符類型賦值(charDemo.java)。
01 //字符類型也可以直接賦給數(shù)值,下面的這段程序就是采用這種賦值方式 02 public class charDemo 03 { 04 public static void main(String args[]) 05 { 06 char ch1=97; 07 char ch2='a'; 08 System.out.println("ch1="+ch1); 09 System.out.println("ch2="+ch2); 10 } 11 }
【運(yùn)行結(jié)果】
程序運(yùn)行結(jié)果如下圖所示。

需要注意的是:字符要用一對單引號(hào)(' ')括起。但如果把一個(gè)字符變量賦值成一個(gè)單引號(hào),就會(huì)出問題,這樣就有了轉(zhuǎn)義字符的概念。轉(zhuǎn)義字符就是用不容易混淆的字符來代替那些敏感字符,它們作為一個(gè)整體使用。
下表為常用的轉(zhuǎn)義字符。

以下面的程序?yàn)槔瑢h賦值為'\"'(要以單引號(hào)(')包圍),并將字符變量ch輸出在顯示器上,同時(shí)在打印的字符串里直接加入轉(zhuǎn)義字符,讀者可自行比較一下兩種方式的差異。
【范例5-9】 轉(zhuǎn)義字符的使用(EscapeChar.java)。
01 //下面這段程序表明了轉(zhuǎn)義字符的使用方法 02 public class EscapeChar 03 { 04 public static void main(String args[]) 05 { 06 char ch='\"'; 07 System.out.println(ch+"測試轉(zhuǎn)義字符!"+ch); 08 System.out.println("\"hello world!\""); 09 } 10 }
【運(yùn)行結(jié)果】
程序運(yùn)行結(jié)果如下圖所示。

總結(jié)可以得知,不管是用變量存放轉(zhuǎn)義字符,還是直接使用轉(zhuǎn)義字符的方式來輸出字符串,程序都可以順利運(yùn)行。由于使用變量會(huì)占用內(nèi)存資源,因此似乎顯得有些不妥;當(dāng)然也可以不必聲明字符變量就輸出轉(zhuǎn)義字符,但如果在程序中加上太多的轉(zhuǎn)義字符,以至于造成混淆而不易閱讀時(shí),利用聲明字符變量的方式就是一個(gè)不錯(cuò)的選擇。
但是需要注意的是,Java之中默認(rèn)采用的編碼方式為Unicode編碼,此編碼是一種采用十六進(jìn)制編碼方案,可以表示出世界上的任意的文字信息。所以在Java之中單個(gè)字符里面是可以保存中文字符的,一個(gè)中文字符占據(jù)2個(gè)字節(jié)。這點(diǎn)是與C/C++對字符型的處理是有區(qū)別的,在C/C++中,中文字符只能當(dāng)作字符串處理。
【范例5-10】 單個(gè)中文字符的使用(ChineseChar.java)。
01 public class ChineseChar 02 { 03 public static void main(String args[]) 04 { 05 char c='中';//單個(gè)字符變量c,存儲(chǔ)單個(gè)中文字母 06 System.out.println(c); 07 } 08 }
【運(yùn)行結(jié)果】
程序運(yùn)行結(jié)果如下圖所示。

值得注意的是,char和int型數(shù)據(jù)的互相轉(zhuǎn)型問題。遵循C語言常用的ASCII碼的習(xí)慣,字母的表示范圍是:大寫字母A~Z對應(yīng)整數(shù)65 ~ 90、小寫字母a~z對應(yīng)整數(shù)97 ~ 122、字符0~9對應(yīng)整型數(shù)49 ~ 57,由此可以發(fā)現(xiàn),大寫字母和小寫字母之間的差是32個(gè)長度,如果按照此規(guī)律,就可以輕易的編寫一個(gè)大小寫的轉(zhuǎn)換操作。參見范例5-12所示。
提示
ASCII(American Standard Code for Information Interchange,美國標(biāo)準(zhǔn)信息交換碼)是計(jì)算機(jī)中用得最廣泛的字符集及其編碼,由美國國家標(biāo)準(zhǔn)局(ANSI)制定,已被國際標(biāo)準(zhǔn)化組織(ISO)定為國際標(biāo)準(zhǔn)。
【范例5-11】 單個(gè)英文字符與ASCII(整型值)的轉(zhuǎn)換(CharToInt.java)。
01 public class CharToInt 02 { 03 04 public static void main(String args[]) 05 { 06 char c='A'; 07 int x=c; //字符c直接給整型變量賦值 08 System.out.println(x); //輸出字符A的ASCII碼值:65 09 x=x+32; //編碼值提升32 10 c=(char)x; //將數(shù)字的編碼值變?yōu)樽址担篴 11 System.out.println(c); 12 13 } 14 }
【運(yùn)行結(jié)果】
程序運(yùn)行結(jié)果如下圖所示。

【范例分析】
范例07行,字符c直接給整型變量賦值x,此時(shí)x的值就是c對應(yīng)的ASCII碼值,也就是65,第08行輸出這個(gè)結(jié)果。
范例第09行,整型變量x值增加32,也就是97,此值正是小寫字母‘a(chǎn)’的ASCII值。第10行將x強(qiáng)制類型轉(zhuǎn)換為字符型,第11行輸出該字符‘a(chǎn)’。
5.5 布爾類型(boolean)
本節(jié)視頻教學(xué)錄像:3分鐘
布爾(Boolean)本是一位英國數(shù)學(xué)家的名字。在Java中使用關(guān)鍵字boolean來聲明布爾類型。被聲明為布爾類型的變量,只有true(真)和false(假)兩種。除此之外,沒有其他的值可以賦值給這個(gè)變量。
布爾類型主要用于邏輯判斷,就如我們?nèi)粘I钪械摹罢妗焙汀凹佟币粯印1热纾覀兛梢杂貌紶栴愋蛠肀硎灸橙说男詣e,“張三”是否是“男人”?如下圖所示。

若想聲明名稱為Zhang3IsMan的變量為布爾類型,并設(shè)置為true值,可以使用下面的語句。
boolean Zhang3IsMan=true; //聲明布爾變量Zhang3IsMan,并賦值為true
經(jīng)過聲明之后,布爾變量的初值即為true,當(dāng)然如果在程序中需要更改status的值時(shí),即可隨時(shí)更改。將上述的內(nèi)容寫成了程序booleanDemo,讀者可以先熟悉一下布爾變量的使用。
【范例5-12】 布爾值類型變量的聲明(booleanDemo.java)。
01 //下面的程序聲明了一個(gè)布爾值類型的變量 02 public class booleanDemo 03 { 04 public static void main(String args[])
05 { 06 //聲明一布爾型的變量status,布爾型只有兩個(gè)取值:true、false 07 boolean Zhang3IsMan=true; 08 System.out.println("Zhang3 is man?="+Zhang3IsMan); 09 } 10 }
【運(yùn)行結(jié)果】
程序運(yùn)行結(jié)果如下圖所示。

【范例分析】
第07行定義一個(gè)布爾變量Zhang3IsMan,并賦值為true。第08行輸出這個(gè)判斷。
特別注意的是,Zhang3IsMan不能賦值為0或者1,或者其他整數(shù),編譯器將不予通過。
布爾值通常用來控制程序的流程,讀者可能會(huì)覺得有些抽象,本書會(huì)陸續(xù)在后面的章節(jié)中介紹布爾值在程序流程中所起的作用。
5.6 數(shù)據(jù)類型的轉(zhuǎn)換
本節(jié)視頻教學(xué)錄像:36分鐘
Java有嚴(yán)格的數(shù)據(jù)類型限制,每種數(shù)據(jù)類型都有其獨(dú)特的特性。這些不同的數(shù)據(jù)類型所定義的變量,它們之間的類型轉(zhuǎn)換不是輕易完成的。但在特殊情況下,還是需要進(jìn)行類型轉(zhuǎn)換的操作,但必須遵循嚴(yán)格的步驟和規(guī)定。數(shù)據(jù)類型的轉(zhuǎn)換方式可分為“自動(dòng)類型轉(zhuǎn)換”及“強(qiáng)制類型轉(zhuǎn)換”兩種。下面分別給予討論。
5.6.1 自動(dòng)類型轉(zhuǎn)換
在程序中已定義好了數(shù)據(jù)類型的變量,若想轉(zhuǎn)換用另一種數(shù)據(jù)類型表示時(shí),Java會(huì)在下面2個(gè)條件皆成立時(shí),自動(dòng)進(jìn)行數(shù)據(jù)類型的轉(zhuǎn)換。
⑴ 轉(zhuǎn)換前后的數(shù)據(jù)類型要相互兼容。在C/C++中,整型和布爾類型的關(guān)系是 “非零即為真”——凡是不是零的整數(shù)都可以認(rèn)為是布爾值為真變量,二者是兼容的,所以可以相互轉(zhuǎn)換。而在Java中,由于boolean類型只能存放true或flase,與整數(shù)及字符不兼容,因此boolean類型不可能與其他任何數(shù)據(jù)類型進(jìn)行轉(zhuǎn)換。整數(shù)與浮點(diǎn)數(shù)亦是兼容的,所以可相互轉(zhuǎn)換。
⑵ 轉(zhuǎn)換后的數(shù)據(jù)類型的表示范圍不小于轉(zhuǎn)換前的類型。以“擴(kuò)大轉(zhuǎn)換”來看可能比較容易理解。Java在進(jìn)行數(shù)值運(yùn)算時(shí),以盡量不損失精度(正確性)為準(zhǔn)則。例如,一個(gè)字符型的變量(本質(zhì)上是2字節(jié)大小的整數(shù))和一個(gè)整型變量(默認(rèn)為4個(gè)字節(jié)大小整數(shù))進(jìn)行計(jì)算,在運(yùn)算前,不同類型的操作數(shù)需要先轉(zhuǎn)化為同一數(shù)據(jù)類型,然后再實(shí)施運(yùn)算操作。因此需要將字符型的變量轉(zhuǎn)換為整型變量,否則將4字節(jié)整型變量轉(zhuǎn)換為2字節(jié)的字符型,很有可能導(dǎo)致整型變量的值會(huì)溢出,從而導(dǎo)致計(jì)算錯(cuò)誤。字符與整數(shù)是可使用自動(dòng)類型轉(zhuǎn)換的。
假設(shè)參與某種運(yùn)算有兩個(gè)不同的操作數(shù)(操作數(shù)1和操作數(shù)2),二者具有不同的數(shù)據(jù)類型,在運(yùn)算操作之前,它們需要轉(zhuǎn)換為同一數(shù)據(jù)類型,其相互轉(zhuǎn)換的規(guī)則如下表所示。

在接下來的范例中,我們來看看當(dāng)兩個(gè)數(shù)中有一個(gè)為浮點(diǎn)數(shù)時(shí),其運(yùn)算的結(jié)果會(huì)有什么樣的變化。
【范例5-13】 聲明兩個(gè)變量,一個(gè)是整型,另一個(gè)是浮點(diǎn)型(IntAndFloat. java)。
01 //下面這段程序聲明了兩個(gè)變量,一個(gè)是整型,另一個(gè)是浮點(diǎn)型 02 public class IntAndFloat 03 { 04 public static void main(String args[]) 05 { 06 int a=156; 07 float b=24.1f; //聲明一浮點(diǎn)型變量f,并賦值24.1 08 System.out.println("a="+a+",b="+b); 09 System.out.println("a/b="+(a/b)); //在這里整型會(huì)自動(dòng)轉(zhuǎn)換為浮點(diǎn)型 10 } 11 }
【運(yùn)行結(jié)果】
程序運(yùn)行結(jié)果如下圖所示。

【范例分析】
從運(yùn)行的結(jié)果可以看出,當(dāng)兩個(gè)數(shù)中有一個(gè)為浮點(diǎn)數(shù)時(shí)(代碼第10行),其運(yùn)算的結(jié)果會(huì)直接轉(zhuǎn)換為浮點(diǎn)數(shù)。當(dāng)表達(dá)式中變量的類型不同時(shí),Java會(huì)自動(dòng)把較小的表示范圍轉(zhuǎn)換成較大的表示范圍后,再做運(yùn)算。也就是說,假設(shè)有一個(gè)整數(shù)和雙精度浮點(diǎn)數(shù)作運(yùn)算,Java會(huì)把整數(shù)轉(zhuǎn)換成雙精度浮點(diǎn)數(shù)后再做運(yùn)算,運(yùn)算結(jié)果也會(huì)變成雙精度浮點(diǎn)數(shù)。關(guān)于表達(dá)式的數(shù)據(jù)類型轉(zhuǎn)換,在后面的章節(jié)中會(huì)有更詳細(xì)的介紹。
現(xiàn)在,我們可以給出自動(dòng)數(shù)據(jù)類型轉(zhuǎn)型的規(guī)律:byte short int long float double,按照范圍由小到大實(shí)現(xiàn)自動(dòng)轉(zhuǎn)型操作。
5.6.2 強(qiáng)制類型轉(zhuǎn)換
當(dāng)程序需要轉(zhuǎn)換數(shù)據(jù)類型時(shí),可實(shí)施強(qiáng)制性的類型轉(zhuǎn)換,其語法如下。
(欲轉(zhuǎn)換的數(shù)據(jù)類型)變量名稱;
下面的程序說明了在Java里,整數(shù)與浮點(diǎn)數(shù)是如何轉(zhuǎn)換的。
【范例5-14】 自動(dòng)轉(zhuǎn)換和強(qiáng)制轉(zhuǎn)換的使用方法(AutoConvert.java)。
01 //下面的范例說明了自動(dòng)轉(zhuǎn)換和強(qiáng)制轉(zhuǎn)換這兩種轉(zhuǎn)換的使用方法 02 public class AutoConvert 03 { 04 public static void main(String args[]) 05 { 06 int a=55; 07 int b=9; 08 float g,h; 09 System.out.println("a="+a+",b="+b); 10 g=a/b; 11 System.out.println("a/b="+g+"\n"); 12 System.out.println("a="+a+",b="+b); 13 h=(float)a/b; //在這里對數(shù)據(jù)類型進(jìn)行強(qiáng)制轉(zhuǎn)換 14 System.out.println("a/b="+h); 15 } 16 }
【運(yùn)行結(jié)果】
程序運(yùn)行結(jié)果如下圖所示。

當(dāng)兩個(gè)整數(shù)相除時(shí),小數(shù)點(diǎn)以后的數(shù)字會(huì)被截?cái)啵沟眠\(yùn)算的結(jié)果保持為整數(shù)。但由于這并不是預(yù)期的計(jì)算結(jié)果,而想要得到運(yùn)算的結(jié)果為浮點(diǎn)數(shù),就必須將兩個(gè)整數(shù)中的一個(gè)(或是兩個(gè))強(qiáng)制轉(zhuǎn)換為浮點(diǎn)數(shù),下面的3種寫法都正確。
(float)a/b; //將整數(shù)a強(qiáng)制轉(zhuǎn)換成浮點(diǎn)數(shù),再與整數(shù)b相除 a/(float)b; //將整數(shù)b強(qiáng)制轉(zhuǎn)換成浮點(diǎn)數(shù),再以整數(shù)a除之 (float)a/(/float)b; //將整數(shù)a與b同時(shí)強(qiáng)制轉(zhuǎn)換成浮點(diǎn)數(shù),再相除
只要在變量前面加上欲轉(zhuǎn)換的數(shù)據(jù)類型,運(yùn)行時(shí)就會(huì)自動(dòng)將此行語句里的變量做類型轉(zhuǎn)換的處理,但這并不影響原先所定義的數(shù)據(jù)類型。
此外,若將一個(gè)超出該變量可表示范圍的值賦給這個(gè)變量,這種轉(zhuǎn)換稱為縮小轉(zhuǎn)換。由于在轉(zhuǎn)換的過程中可能會(huì)丟失數(shù)據(jù)的精確度,因此Java并不會(huì)“自動(dòng)”做這些類型的轉(zhuǎn)換,此時(shí)就必須要做強(qiáng)制性的轉(zhuǎn)換,例如 int x = (int)10.35(結(jié)果x=10),將double類型的值(10.35)強(qiáng)制轉(zhuǎn)換為int類型(10),這樣也丟失了很多的信息。
5.7 基本數(shù)據(jù)類型的默認(rèn)值
本節(jié)視頻教學(xué)錄像:10分鐘
在Java中,若在變量的聲明時(shí)沒有賦初值,則會(huì)給該變量賦默認(rèn)值。下表列出了各種類型的默認(rèn)值。

在某些情形下,Java會(huì)給予這些沒有賦初始值的變量一個(gè)確切的默認(rèn)值,這個(gè)值沒有任何意義,但保證程序執(zhí)行時(shí),不運(yùn)行有這種沒有初始化值的變量存在。雖然這種方式給程序編寫者帶來了很多便利,但是過于依賴系統(tǒng)給變量賦初值,就不容易檢測到是否已經(jīng)給予變量應(yīng)有的值了,這是個(gè)需要注意的問題。
5.8 高手點(diǎn)撥
本節(jié)視頻教學(xué)錄像:9分鐘
1. 整型數(shù)的除法要注意
由于整數(shù)與整數(shù)運(yùn)算,其結(jié)果還是整數(shù),除法也不例外,而很多初學(xué)者受到數(shù)學(xué)上的慣性思維影響,沒有能充分注意,導(dǎo)致在一些考試題(面試題)中失利,請參見下面的例程,寫出程序的輸出結(jié)果:
01 public class Demo 02 { 03 public static void main(String args[]) 04 { 05 int x=10; 06 int y=3; 07 int result=x/y; 08 System.out.println(result); 09 } 10 }
分析:由于x和y均是整數(shù),在數(shù)據(jù)類型上,int型 / int型 = int型,所以x / y=10/3=3,而不是。本題的輸出為3,即
的整數(shù)部分。
2. C/C++語言和Java語言在布爾類型上存在顯著差別
從C/C++語言過渡來學(xué)習(xí)Java的讀者,請注意Java語言與C/C++在布爾類型上有很大區(qū)別,C/C++遵循的規(guī)則是 “非零即為真”,即所有不是零的數(shù),都可認(rèn)為是“true”,而僅把0當(dāng)作false。
而Java語言的布爾類型變量,其賦值只能是true(真)和false(假)兩種。除此之外,沒有其他的值可以賦值給布爾變量。也不能用1和0分別代替true(真)和false(假)。一言蔽之,Java語言中的布爾類型與整型無關(guān)。
5.9 實(shí)戰(zhàn)練習(xí)
本節(jié)視頻教學(xué)錄像:20分鐘
1. 編寫程序,要求運(yùn)行后要輸出long類型數(shù)據(jù)的最小數(shù)和最大數(shù)。
2. 改錯(cuò)題:指出錯(cuò)誤之處并對其進(jìn)行修改(本題改編自2013年巨人網(wǎng)絡(luò)的Java程序員筆試題)。
程序功能:輸出int類型最小值與最大值之間的所有數(shù)是否是偶數(shù)(能被2整除的數(shù)),操作符%為求余操作。
01 public class FindEvenNumber 02 { 03 public static void main(String[]args) 04 { 05 for(int i=Integer.MIN_VALUE;i<=Integer.MAX_VALUE;++i)
06 { 07 boolean isEven=(i%2==0); 08 System.out.println(String.format("i=%d,isEven=%b",i,isEven)); 09 } 10 } 11 }
3. 請運(yùn)行下面一段程序,并分析產(chǎn)生輸出結(jié)果的原因(改編自網(wǎng)絡(luò)Java面試題)。
01 public class CTest 02 { 03 public static void main(String[]args) 04 { 05 06 int x=5; 07 int y=2; 08 System.out.println(x+y+"K"); 09 System.out.println(6+6+"aa"+6+6); 10 } 11 }
【運(yùn)行結(jié)果】

【面試題分析】
對于第08行,按照運(yùn)算符從左至右的運(yùn)算順序,第一個(gè)運(yùn)算表達(dá)式是5+2=7,之后運(yùn)算表達(dá)式為7 + “K”,因?yàn)椤癒”是字符串,通過類型轉(zhuǎn)換之后將7轉(zhuǎn)換為字符,這里第二個(gè)加號(hào)“+”相當(dāng)于一個(gè)字符串連接符。所以第08行的輸出結(jié)果為7K。同理可分析第09行的輸出,第一個(gè)運(yùn)算表達(dá)式是6 + 6= 12,之后運(yùn)算表達(dá)式為12 + “aa”,因?yàn)椤癮a”是字符串,整型12被轉(zhuǎn)換為字符串“12”。通過加號(hào)連接符構(gòu)成新的字符串“12aa”。類似的,系統(tǒng)會(huì)自動(dòng)將“12aa”后面的兩個(gè)整數(shù)“6”,逐個(gè)轉(zhuǎn)換成字符“6”,然后通過加號(hào)“+”連接成新的字符串,最終形成輸出的字符串“12aa66”。
請讀者思考一下,如果將08行字符“K”的雙引號(hào)“ ”換成單引號(hào)‘ ’,即。
System.out.println(x + y + ‘K’);
請寫出相應(yīng)的輸出結(jié)果,并分析原因。
- VMware vSphere 7.0云平臺(tái)運(yùn)維與管理(第2版)
- Android 網(wǎng)絡(luò)開發(fā)與應(yīng)用實(shí)戰(zhàn)詳解
- DevSecOps企業(yè)級實(shí)踐:理念、技術(shù)與案例
- Android插件化開發(fā)指南
- 學(xué)校沒教的軟件工程課
- 這就是MCP
- 軟件測試之魂:核心測試設(shè)計(jì)精解
- 軟件架構(gòu)的藝術(shù)
- 負(fù)載均衡:高并發(fā)網(wǎng)關(guān)設(shè)計(jì)原理與實(shí)踐
- 虛擬現(xiàn)實(shí):科技新浪潮
- 統(tǒng)信UOS應(yīng)用開發(fā)詳解
- React Cookbook中文版:87個(gè)案例帶你精通React框架
- 微信小程序?qū)崙?zhàn)入門(內(nèi)含完整實(shí)例解析)
- 云原生測試實(shí)戰(zhàn)
- 大話軟件工程案例篇:項(xiàng)目與產(chǎn)品開發(fā)實(shí)戰(zhàn)