天天看點

《Java從小白到大牛精簡版》之第5章 資料類型

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

《Java從小白到大牛精簡版》之第5章 資料類型

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

5.1 基本資料類型

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

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

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

《Java從小白到大牛精簡版》之第5章 資料類型

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類型取值範圍0~216-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所示,從左到右是自動。

《Java從小白到大牛精簡版》之第5章 資料類型

注意 如圖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從小白到大牛精簡版》之第5章 資料類型

提示 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從小白到大牛精簡版》之第5章 資料類型
《Java從小白到大牛精簡版》之第5章 資料類型

本章小結

配套視訊