1. 程式人生 > >「MoreThanJava」Day2:變數、資料型別和運算子

「MoreThanJava」Day2:變數、資料型別和運算子

![](https://imgkr.cn-bj.ufileos.com/9eac5907-2a62-4665-911a-ba7a0927bdc8.png) - **「MoreThanJava」** 宣揚的是 **「學習,不止 CODE」**,本系列 Java 基礎教程是自己在結合各方面的知識之後,對 Java 基礎的一個總回顧,旨在 **「幫助新朋友快速高質量的學習」**。 - 當然 **不論新老朋友** 我相信您都可以 **從中獲益**。如果覺得 **「不錯」** 的朋友,歡迎 **「關注 + 留言 + 分享」**,文末有完整的獲取連結,您的支援是我前進的最大的動力! # Part 1. 資料型別 ![](https://imgkr.cn-bj.ufileos.com/eb90cb38-53e4-4b46-9556-836f3007cbfa.png) 假設您遇到了以下撕碎的紙片,您覺得會是什麼意思? ![](https://imgkr.cn-bj.ufileos.com/fb561ec0-f171-4b46-9458-e91f786a7be6.png) 在不瞭解上下文的情況下,很難說出 `MIX` 的含義,它可能是羅馬數字 `1009`,也可以是英語單詞 `mix` 或者別的什麼東西。 在不知道上下文的情況下,一串字母沒有任何意義。 與一串字母一樣,一串 `01` 的含義取決於如何使用。而決定這一串資料如何使用的方案被稱為其 **資料型別** *(跟檔案型別有些類似)*。 ## 8 種基本資料型別 **Java 是一種強型別語言**。這意味著必須為每一條資料宣告一種型別。在 Java 中共有 `8` 種基本型別 *(primitive type)*,其中 `4` 種整型、`2` 種浮點型別、`1` 種字元型別、`1` 種表示真值的 `boolean` *(布林)* 型別。 ### 整型 整型被用來表示沒有小數部分的數值,允許是負數。Java 提供了 `4` 種整型,具體內容如下: 型別 | 儲存需求 | 取值範圍 :-- | :-- | :-- int | 4 位元組 | -2147483648 ~ 2147483647 *(剛超過 `20` 億,這個數值也就是 232 對半分成正負值,`32=4位元組*每個位元組8位`)* short | 2 位元組 | -32768 ~ 32767 long | 8 位元組 | -9223372036854775808 ~ 9223372036854775807 byte | 1 位元組 | -128 ~ 127 在通常情況下,`int` 型別最常用。但如果想要表示整個地球的居住人口,那麼就需要使用 `long` 型別了。`byte` 和 `short` 型別主要用於特定的應用場合,例如,底層的檔案處理或者儲存空間很寶貴時的大陣列 *(因為節約記憶體)*。 ### 浮點型別 浮點型別用於表示有小數部分的數值。在 Java 中有兩種浮點型別,具體內容如下: 型別 | 儲存需求 | 取值範圍 :-- | :-- | :-- float | 4 位元組 | 大約 ±3.40282347E + 38F *(大約有效數為 6 ~ 7)* double | 8 位元組 | 大約 ±1.7976931486231580E + 308 *(大約有效數為 15 位)* `double` 表示這種型別的數值精度是 `float` 型別的兩倍 *(也有人稱 `double` 為雙精度數值)*。 #### 浮點數精度問題 問一個問題:`0.1 + 0.2 = ?` ![](https://imgkr.cn-bj.ufileos.com/e0802eac-eb7b-40bb-b816-893ead0099f4.png) 先別奇怪,在 IDEA 中嘗試著輸出一下這句話就知道了: ```java System.out.println(0.1 + 0.2); // 輸出:0.30000000000000004 ``` `0.1 + 0.2` 為什麼會等於 `0.30000000000000004`?而不是我們想象中的 `0.3`? **這不是因為它們在計算時出現了錯誤,而是因為浮點數計算標準的要求。** 首先我們要明確一點:**程式設計中的浮點數並不能和數學中的小數看做同一個東西**。 - 程式設計中的浮點數的精度往往都是有限的,單精度的浮點數使用 `32` 位表示,而雙精度的浮點數使用 `64` 位表示; - 數學中的小數系統可以通過引入無限序列....可以表示任意的實數; 請考慮使用 **十進位制** 表示 `1/3`: ```console 0.3333333333333333.... ``` 如果想要完整地表達 `1/3` 的精度,那麼小數點之後的 `3` 需要無限地寫下去。如果需要讓你在一張紙上表達清晰,顯然由於紙張大小的限制你無法無限地寫下去... `0.1` 和 `0.2` 在 **二進位制** 中同 `1/3` 在 **十進位制** 中一樣,不屬於整數的範疇,所以只能用近似值來代替,由於精度的限制 `0.1` 和 `0.2` 使用單精度浮點數表示的實際值為:`0.100000001490116119384765625` 和 `0.20000000298023223876953125`,把它們相加起來得到的結果與我們在一開始看到的非常相似: ![](https://imgkr.cn-bj.ufileos.com/462ec222-4fb5-4f48-8630-899dd8348338.png) 在交易系統或者科學計算的場景中,如果需要更高的精度小數,可以使用具有 `28` 個有效位數的 `decimal` 或者直接使用分數,不過這些表示方法的開銷也隨著有效位數的增加而提高,我們應該按照需要選擇最合適的方法。 重新回到最開始的問題 — `0.1` 和 `0.2` 相加不等於 `0.3` 的原因包括以下兩個: - 使用二進位制表達十進位制的小數時,某些數字無法被有限位的二進位制小數表示; - 單精度和雙精度的浮點數只包括 `7` 位或者 `15` 位的有效小數位,儲存需要無限位表示的小數時只能儲存近似值; **在使用單精度和雙精度浮點數時也應該牢記它們只有 `7` 位和 `15` 位的有效位數**。 ### char 型別 `char` 用來表示單個字元。在 Java 中 `char` 型別的資料使用 `16` 位來儲存和表示,而許多程式語言則僅用 `8` 位。 `char` 型別的字面量值需要用 **單引號** 括起來。例如:`'A'` 是編碼值為 `65` 的 **字元常量**,它與 `"A"` 不同,`"A"` 是僅包含字元 `A` 的 **字串** *(String 型別)*。 **強烈建議**:不要在程式中使用 `char` 型別,除非您確實需要處理 `UTF-16` 程式碼單元。 *(更多相關資料放入了下面的自取資料,感興趣可以去閱讀一下更多 char 型別的東西,不感興趣跳過即可...)* ### boolean 型別 `boolean` *(布林)* 型別有兩個值:`false` 和 `true` *(注意這兩個是布林型別的字面常量也是保留字)*,用來判斷邏輯條件是否成立。 ## 物件型別 **Java 中的所有資料都屬於「基本資料型別」或「物件」中的一種。** 雖然只有八種基本資料型別,但 Java 有許多滿足您需求的相關型別的物件供您使用,例如,表示字串的 `String` 型別。 我們會在之後的內容中更多地討論物件 *(因為 Java 是一種面向物件的程式語言)*,現在,您需要了解以下資訊: - 基本資料型別使用少量的固定位元組數 *(下面會詳細介紹)*; - 只有 `8` 種基本資料型別,您無法建立新的原始資料型別; - 一個物件是一個較大的資料塊,可能使用很多位元組的記憶體; - 物件型別的資料被稱為 **類**; - Java 中已經封裝了足夠多的類用來滿足您各類的需求,您也可以發明新的類來滿足程式的特定需求; # Part 2. 變數 ![](https://imgkr.cn-bj.ufileos.com/e59bfd69-e4be-4dba-ad62-3fc8e0a8218d.png) **計算機記憶體中有數以十億計的位元組用於儲存機器指令和資料。** 程式執行時,某些記憶體用於儲存機器指令,而另外一些則用於儲存資料。後來,當另一個程式執行時,以前儲存的機器指令中的某些位元組現在可以用來儲存資料,而之前儲存的資料中的某些位元組現在可以儲存機器指令。 計算機先驅 **約翰·馮·諾依曼** *(John von Neumann)* 的想法是:**使用相同的儲存器來儲存指令和資料**。 回想一下,**資料型別是一種使用位模式來表示值的方案**。 ![](https://imgkr.cn-bj.ufileos.com/a3a9a56a-9162-46e0-86b5-4ee21b806557.png) 可以把 **變數** 視為一個由一個或多個位元組組成的小盒子,該盒子可以使用特定的資料型別儲存值。 要將值儲存在記憶體中,以後再取回它,則程式必須為每個變數指定一個名稱,如 `className`/ `payAmount` **(變數名採用小駝峰命名法)**。 變數隨執行程式的需要而變化。當正在執行的程式不再需要變數時,該記憶體部分可用於其他目的。 ## 宣告變數 在 Java 中,每個變數都必須有一個型別 *(type)*。在宣告變數時,需要先指定變數的型別,然後是變數名: ```java double salary; int vacationDays; long earthPopluation; boolean finished; ``` 可以看到,每個變數都以分號 *(`;`)* 結束。由於宣告是一條完整的 Java 語句,而所有的 Java 語句都以分號結束,所以這裡的分號是必須的。 ### 變數命名 在 Java 中,變數命名需要遵循以下硬性規定和強烈建議遵守的非硬性規定: #### 硬性規則 1. 變數名必須是一個以字母開頭並由字母或數字構成的序列 *(儘管 `$` 是合法的,但不要在你自己的程式碼中使用這個字元,它只用在 Java 編譯器或其他工具生成的名字中)*; 1. 每一個字元都有意義,且大小寫敏感; 1. 不要使用 Java 中的保留字; #### 《阿里巴巴 Java 開發手冊》規則 1. **【強制】** 程式碼中的命名 *(所有識別符號)* 均不能以下劃線或美元符號開始,也不能以下劃線或美元符號結束;*(反例: `$name`)* 1. **【強制]** 程式碼中的命名嚴禁使用拼音與英文混合的方式,更不允許直接使用中文的方式;*(反例:`DaZhePromotion` - 打折)* 1. **【強制】** 杜絕完全不規範的縮寫,避免詞不達意;*(反例:`condition` 縮寫成 `condi`)* 1. **【推薦】** 為了達到程式碼自解釋的目的,任何自定義程式設計元素在命名時,使用盡量完整的單詞組合來表達其意;*(反例:`int a;` 的隨意命名方式)* ## 變數初始化 **宣告一個變數之後,必須用賦值語句對變數進行顯式初始化,千萬不要使用未初始化的變數的值**。例如,Java 編譯器認為下面的語句序列是錯誤的: ```java int amount; System.out.println(amount); // ERROR -- variable not initialized ``` 要相對一個已經宣告過的變數進行賦值,就需要將變數名放在等號 *(`=`)* 左側,再把一個適當取值放在等號的右側: ```java int amount; amount = 12; ``` 也可以將變數的宣告和初始化放在同一行中。例如: ```java int amount = 12; ``` 最後,在 Java 中可以將宣告放在程式碼中的任何地方。 但讓變數儘可能地靠近變數第一次使用的地方,這是一種良好的程式編寫風格。 ## 變數使用範例 我們來使用變數完成兩個數的加減乘除: ```java int num1 = 2; int num2 = 3; System.out.println(num1 + num2); System.out.println(num1 - num2); System.out.println(num1 * num2); System.out.println(num1 / num2); ``` # Part 3. 運算子 ![](https://imgkr.cn-bj.ufileos.com/39846f38-0dfe-4e04-b3a8-ce140174aedd.png) 計算機的最基本用途之一就是執行數學運算,作為一門計算機語言,Java 也提供了一套豐富的運算子來操縱變數。我們可以把運算子分成以下幾組: - 算術運算子; - 關係運算符; - 位運算子; - 邏輯運算子; - 賦值運算子; - 其他運算子; ## 算術運算子 算術運算子用在數學表示式中,它們的作用和在數學中的作用一樣。下表列出了所有的算術運算子。 表格中的例項假設整數變數 `A` 的值為 `10`,變數 `B` 的值為 `20`: ![](https://imgkr.cn-bj.ufileos.com/a69a5dbc-190c-4c29-8b11-5313bf04f3e5.png) ### 例項 下面的簡單示例程式演示了算術運算子。複製並貼上下面的 Java 程式並儲存為 `Test.java` 檔案,然後編譯並執行這個程式: ```java public class Test { public static void main(String[] args) { int a = 10; int b = 20; int c = 25; int d = 25; System.out.println("a + b = " + (a + b)); System.out.println("a - b = " + (a - b)); System.out.println("a * b = " + (a * b)); System.out.println("b / a = " + (b / a)); System.out.println("b % a = " + (b % a)); System.out.println("c % a = " + (c % a)); System.out.println("a++ = " + (a++)); System.out.println("a-- = " + (a--)); // 檢視 d++ 與 ++d 的不同 System.out.println("d++ = " + (d++)); System.out.println("++d = " + (++d)); } } ``` **執行結果:** ```console a + b = 30 a - b = -10 a * b = 200 b / a = 2 b % a = 0 c % a = 5 a++ = 10 a-- = 11 d++ = 25 ++d = 27 ``` ### i++ 與 ++i 到底有什麼不同? **實際上,不管是`前置 ++`,還是`後置 ++`,都是先將變數的值加 `1`,然後才繼續計算的。** **二者之間真正的區別是**:`前置 ++` 是將變數的值加 `1` 後,使用增值後的變數進行運算的,而`後置 ++` 是首先將變數賦值給一個臨時變數,接下來對變數的值加 `1`,然後使用那個臨時變數進行運算。 ![](https://imgkr.cn-bj.ufileos.com/08c5a27f-3655-4167-b832-775506885eff.png) ## 關係運算符 下表為Java支援的關係運算符。 表格中的例項整數變數 `A` 的值為 `10`,變數 `B` 的值為 `20`: ![](https://imgkr.cn-bj.ufileos.com/c4b0c001-526f-424c-b177-11b5b7ba0c1b.png) ### 例項 下面的簡單示例程式演示了關係運算符。複製並貼上下面的 Java 程式並儲存為 `Test.java` 檔案,然後編譯並執行這個程式: ```java public class Test { public static void main(String[] args) { int a = 10; int b = 20; System.out.println("a == b = " + (a == b)); System.out.println("a != b = " + (a != b)); System.out.println("a >
b = " + (a > b)); System.out.println("a < b = " + (a < b)); System.out.println("b >= a = " + (b >= a)); System.out.println("b <= a = " + (b <= a)); } } ``` **執行結果:** ```console a == b = false a != b = true a > b = false a < b = true b >= a = true b <= a = false ``` ## 位運算子 Java定義了位運算子,應用於整數型別 *(int)*,長整型 *(long)*,短整型 *(short)*,字元型 *(char)*,和位元組型 *(byte)* 等型別。 位運算子作用在所有的位上,並且按位運算。假設 `a = 60,b = 13;` 它們的二進位制格式表示將如下: ```console A = 0011 1100 B = 0000 1101 ----------------- A&B = 0000 1100 A | B = 0011 1101 A ^ B = 0011 0001 ~A = 1100 0011 ``` 下表列出了位運算子的基本運算,假設整數變數 `A` 的值為 `60` 和變數 `B` 的值為 `13`: ![](https://imgkr.cn-bj.ufileos.com/b667545b-3c1c-497e-ae5f-9d40ec61ca2e.png) ### 例項 下面的簡單示例程式演示了關係運算符。複製並貼上下面的 Java 程式並儲存為 `Test.java` 檔案,然後編譯並執行這個程式: ```java public class Test { public static void main(String[] args) { int a = 60; /* 60 = 0011 1100 */ int b = 13; /* 13 = 0000 1101 */ int c = 0; c = a & b; /* 12 = 0000 1100 */ System.out.println("a & b = " + c); c = a | b; /* 61 = 0011 1101 */ System.out.println("a | b = " + c); c = a ^ b; /* 49 = 0011 0001 */ System.out.println("a ^ b = " + c); c = ~a; /*-61 = 1100 0011 */ System.out.println("~a = " + c); c = a << 2; /* 240 = 1111 0000 */ System.out.println("a << 2 = " + c); c = a >> 2; /* 15 = 1111 */ System.out.println("a >> 2 = " + c); c = a >>> 2; /* 15 = 0000 1111 */ System.out.println("a >>> 2 = " + c); } } ``` **執行結果:** ```console a & b = 12 a | b = 61 a ^ b = 49 ~a = -61 a << 2 = 240 a >> 2 = 15 a >>> 2 = 15 ``` ## 邏輯運算子 下表列出了邏輯運算子的基本運算,假設布林變數 `A` 為真,變數 `B` 為假: ![](https://imgkr.cn-bj.ufileos.com/afb5f937-7e75-4a14-95fe-034ba0c278fd.png) ### 例項 下面的簡單示例程式演示了關係運算符。複製並貼上下面的 Java 程式並儲存為 `Test.java` 檔案,然後編譯並執行這個程式: ```java public class Test { public static void main(String[] args) { boolean a = true; boolean b = false; System.out.println("a && b = " + (a && b)); System.out.println("a || b = " + (a || b)); System.out.println("!(a && b) = " + !(a && b)); } } ``` **執行結果:** ```console a && b = false a || b = true !(a && b) = true ``` ### 短路邏輯運算子 當使用與邏輯運算子時,在兩個運算元都為 `true` 時,結果才為 `true`,但是當得到第一個操作為 `false` 時,其結果就必定是 `false`,這時候就不會再判斷第二個操作了。 事實上,如果所有的邏輯表示式都有一部分不必計算,那將獲得潛在的效能提升。 **例項:** ```java public class LuoJi { public static void main(String[] args) { int a = 5;//定義一個變數; boolean b = (a < 4) && (a++ < 10); System.out.println("使用短路邏輯運算子的結果為" + b); System.out.println("a的結果為" + a); } } ``` **執行結果:** ```console 使用短路邏輯運算子的結果為false a的結果為5 ``` ## 賦值運算子 下面是 Java 語言支援的賦值運算子: ![](https://imgkr.cn-bj.ufileos.com/51d1852a-9609-4d1e-949a-6fef481e064d.png) ### 例項 下面的簡單示例程式演示了關係運算符。複製並貼上下面的 Java 程式並儲存為 `Test.java` 檔案,然後編譯並執行這個程式: ```java public class Test { public static void main(String[] args) { int a = 10; int b = 20; int c = 0; c = a + b; System.out.println("c = a + b = " + c); c += a; System.out.println("c += a = " + c); c -= a; System.out.println("c -= a = " + c); c *= a; System.out.println("c *= a = " + c); a = 10; c = 15; c /= a; System.out.println("c /= a = " + c); a = 10; c = 15; c %= a; System.out.println("c %= a = " + c); c <<= 2; System.out.println("c <<= 2 = " + c); c >>= 2; System.out.println("c >>= 2 = " + c); c >>= 2; System.out.println("c >>= 2 = " + c); c &= a; System.out.println("c &= a = " + c); c ^= a; System.out.println("c ^= a = " + c); c |= a; System.out.println("c |= a = " + c); } } ``` **執行結果:** ```console c = a + b = 30 c += a = 40 c -= a = 30 c *= a = 300 c /= a = 1 c %= a = 5 c <<= 2 = 20 c >>= 2 = 5 c >>= 2 = 1 c &= a = 0 c ^= a = 10 c |= a = 10 ``` ## 其他運算子 ### 條件運算子 (?:) 條件運算子也被稱為三元運算子。該運算子有 `3` 個運算元,並且需要判斷布林表示式的值。該運算子的主要是決定哪個值應該賦值給變數。 ```java variable x = (expression) ? value if true : value if false ``` ### 例項 下面的簡單示例程式演示了關係運算符。複製並貼上下面的 Java 程式並儲存為 `Test.java` 檔案,然後編譯並執行這個程式: ```java public class Test { public static void main(String[] args) { int a, b; a = 10; // 如果 a 等於 1 成立,則設定 b 為 20,否則為 30 b = (a == 1) ? 20 : 30; System.out.println("Value of b is : " + b); // 如果 a 等於 10 成立,則設定 b 為 20,否則為 30 b = (a == 10) ? 20 : 30; System.out.println("Value of b is : " + b); } } ``` **執行結果:** ```console Value of b is : 30 Value of b is : 20 ``` ### instanceof 運算子 該運算子用於操作物件例項,檢查該物件是否是一個特定型別(類型別或介面型別)。 `instanceof` 運算子使用格式如下: ```java ( Object reference variable ) instanceof (class/interface type) ``` 如果運算子左側變數所指的物件,是操作符右側類或介面 *(class/interface)* 的一個物件,那麼結果為真。 下面是一個例子: ```java String name = "James"; boolean result = name instanceof String; // 由於 name 是 String 型別,所以返回真 ``` # 要點回顧 1. Java 是一種強型別語言,任何一種資料都屬於 `1` 種基本型別或者物件型別 *(類)* 中的一種; 1. `8` 種基本資料型別; 1. 為什麼引入變數、如何定義使用變數以及變數名的命名規範; 1. Java 中的運算子以及使用例項; # 練習 ## 獲取使用者輸入 Scanner `java.util.Scanner` 是 Java5 的新特徵,我們可以通過 `Scanner` 類來獲取使用者的輸入。 下面是建立 Scanner 物件的基本語法: ```java Scanner scanner = new Scanner(System.in); ``` 在下面的示例中,我們將使用該類的 `nextLine()` 方法,該方法用於讀取字串: ```java import java.util.Scanner; // Import the Scanner class class MyClass { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); // Create a Scanner object System.out.println("Enter username"); String userName = scanner.nextLine(); // Read user input System.out.println("Username is: " + userName); // Output user input } } ``` ### 輸入型別 在上面的示例中,我們使用了 `nextLine()` 用於讀取字串的方法。要閱讀其他型別,請查看下錶: ![](https://imgkr.cn-bj.ufileos.com/26168eb3-f7b9-4b26-817f-7308ff381dbf.png) - 引用自:https://www.w3schools.com/java/java_user_input.asp ## 練習 1:輸入圓的半徑計算周長和麵積 參考答案: ```java import java.util.Scanner; public class Tester { public static void main(String[] args) { System.out.println("請輸入圓的半徑:"); Scanner scanner = new Scanner(System.in); int radius = scanner.nextInt(); // 計算周長和麵積 double area = radius * radius * 3.14; double perimeter = 2 * 3.14 * radius; System.out.println("該圓的面積為:" + area); System.out.println("該圓的周長為:" + perimeter); } } ``` ## 練習 2:輸入年份判斷是不是閏年 提示: 閏年需要滿足: 1. 能被 `4` 整除,並且不能被 `100` 整除; 1. 或者能被 `400` 整除; 參考答案: ```java import java.util.Scanner; public class Tester { public static void main(String[] args) { System.out.println("請輸入年份:"); Scanner scanner = new Scanner(System.in); int year = scanner.nextInt(); boolean leapYear; boolean divisbleBy4 = year % 4 == 0; boolean notDivisbleBy100 = year % 100 != 0; boolean divisibleBy400 = year % 400 == 0; leapYear = (divisbleBy4 && notDivisbleBy100) || divisibleBy400; System.out.println("該年份是否是閏年:" + leapYear); } } ``` # 自取資料 ## 擴充套件閱讀推薦 1. Java 基本資料型別 | 菜鳥教程 - https://www.runoob.com/java/java-basic-datatypes.html 1. 浮點型別精度深度討論: 1. 為什麼 0.1 + 0.2 = 0.3? - https://draveness.me/whys-the-design-decimal-and-rational/ 1. 為什麼 0.1 + 0.2 = 0.300000004? - https://draveness.me/whys-the-design-floating-point-arithmetic/#fn:2 1. IEEE754標準: 浮點數在記憶體中的儲存方式 - https://www.jianshu.com/p/8ee02e9bb57d 1. 為什麼Java中char型別不能完整表示一個字元? - https://fookwood.com/java-string-charset-char ## 推薦書籍 #### Java 核心技術·卷 I(原書第 11 版) ![](https://imgkr.cn-bj.ufileos.com/1ed33e34-7d6d-4d05-8849-9f60a278726c.png) **推薦理由:** 這本書在知識體系完整充實的同時,又比《Thinking in Java》暴風式的知識洗禮來得輕鬆,新人入門書籍強烈推薦! #### 碼出高效:Java開發手冊 ![](https://imgkr.cn-bj.ufileos.com/87b25b84-8ecc-4196-980b-3f73811c48e9.png) **推薦理由:** 阿里系出品。從最基礎的計算機基礎入手,到 Java 的方方面面,加上精美的配圖和通俗易懂的解釋,是非常適合新手閱讀的一本兒關於 Java 的技術書籍。 # 參考資料 1. Introduction to Computer Science using Java - http://programmedlessons.org/Java9/index.html#part02 1. Java 運算子 | 菜鳥教程 - https://www.runoob.com/java/java-operators.html 1. 《Java 核心技術 卷I》(第11版) > - 本文已收錄至我的 Github 程式設計師成長系列 **【More Than Java】,學習,不止 Code,歡迎 star:[https://github.com/wmyskxz/MoreThanJava](https://github.com/wmyskxz/MoreThanJava)** > - **個人公眾號** :wmyskxz,**個人獨立域名部落格**:wmyskxz.com,堅持原創輸出,下方掃碼關注,2020,與您共同成長! ![](https://imgkr.cn-bj.ufileos.com/ace97ed9-3cfd-425f-85e5-c1a1e5ca7d3f.png) 非常感謝各位人才能 **看到這裡**,如果覺得本篇文章寫得不錯,覺得 **「我沒有三顆心臟」有點東西** 的話,**求點贊,求關注,求分享,求留言!** 創作不易,各位的支援和認可,就是我創作的最大動力,我們下篇文