《Java從小白到大牛》之第5章 數據類型

《Java從小白到大牛》紙質版已經上架了!!!

在聲明變量或常量時會用到數據類型,在前面已經用到一些數據類型,例如int、double和String等。Java語言的數據類型分為:基本類型和引用類型。

5.1 基本數據類型

基本類型表示簡單的數據,基本類型分為4大類,共8種數據類型。

  • 整數類型:byte、short、int和long
  • 浮點類型:float和double
  • 字符類型:char
  • 布爾類型:boolean

基本數據類型如圖5-1所示,其中整數類型、浮點類型和字符類型都屬于數值類型,它們之間可以互相轉換。

圖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 數據類型轉換順序

注意 如圖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所示,包含:類、接口和數組聲明的數據類型。

圖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所示。

圖5-4 引用數據類型賦值過程1
圖5-5 引用數據類型賦值過程2

本章小結

本章主要介紹了Java中的數據類型,讀者需要重點掌握基本數據類型,理解基本數據類型與引用數據類型的區別,熟悉數值類型如何互相轉換。

配套視頻

http://www.zhijieketang.com/classroom/6/courses

配套源代碼

http://www.zhijieketang.com/group/5

與本書免費版對應的還有一個收費版本:

  1. 進入百度閱讀電子書

  2. 進入圖靈社區電子書

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,963評論 6 542
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,348評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,083評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,706評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,442評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,802評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,795評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,983評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,542評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,287評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,486評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,030評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,710評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,116評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,412評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,224評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,462評論 2 378