張小飛的Java之路——第三章
1. java 程序的5大部分
諸小亮:“師弟,接下來我們就要聊一聊 Java 程序的構(gòu)成了”
張小飛:“好啊,終于開始正題了”
“一個完整的 Java 程序由很多部分共同組成,比如:關(guān)鍵字、標(biāo)識符、注釋、常量、變量。。。”
“停停停,師兄,您的意思是,之前的程序里有這么多東西?但是看著沒你說的這么復(fù)雜啊”
“之前的只是入門程序,里面包含的東西并不全,只包含的有關(guān)鍵字、標(biāo)識符這兩項”
“原來是這樣”
1. Java內(nèi)置的——關(guān)鍵字
諸小亮:“咱們首先看——關(guān)鍵字”
關(guān)鍵字:Java 定義的,一些有特殊含義的單詞(都是小寫)
下圖中,高亮的就是關(guān)鍵字

“師兄,不是用 IDEA 嗎,怎么又用上記事本了”
“這可不是記事本,而是 Notepad++,是一個文本編輯器,剛才的 IDEA 只是讓你熟悉一下,前期我們以Notepad++ 為主來編寫程序,讓你練一練手速 ”
“那剛才還安裝 idea 干嘛?”張小飛不滿的說到
“熟悉一下嘛,idea后面會用的,另外,在命令行中執(zhí)行程序是非常重要的,會讓你有很大的收獲,這是每個人都應(yīng)該體驗的一個過程,一定要相信我”諸小亮鄭重的說到
“明白”張小飛看到師兄的表情,也不由的重視起來
“不過,關(guān)鍵字只有上面的 4 個嗎?”
“不是的,關(guān)鍵字有很多,不過我們現(xiàn)在不會一個個的介紹,之后寫程序的時候遇到一個說一個”
“。。。。,好吧”
2. 自己定義的——標(biāo)識符
諸小亮:“接下來,我們學(xué)習(xí)——標(biāo)識符”
標(biāo)識符:是自己在程序中自定義的名稱
下圖紅框中的都是:

張小飛:“我總結(jié)一下:java定義的叫關(guān)鍵字,我們自己定義的叫標(biāo)識符,是這個意思吧”
“沒錯,不過標(biāo)識符不能隨便定義,要遵守一些規(guī)則:”
● 標(biāo)識符只能由 a-z,0-9, _ 和 $ 組成,還需注意: ? ?○ 數(shù)字不可以開頭 ? ?○ 不能使用關(guān)鍵字 ? ?○ 在起名字的時,為了提高閱讀性,要盡量有意義
“師兄,能不能列舉幾個例子”
“當(dāng)然可以,看看這幾個:”
“好的,我大概明白了”
3. 容易理解的——注釋
張小飛:“注釋是什么意思?”
諸小亮:“Java 是外國人開發(fā)的,代碼一般都是英文,相對來說不容易理解”
注釋:可以讓我們用一些文字對程序進行說明,提高代碼的閱讀性
比如:

“哦,原來如此,確實容易理解多了,不過,注釋都是以 ‘//’ 開頭嗎?”
“在 Java 中的注釋有 3 種:單行注釋、多行注釋、文檔注釋”
單行注釋:以“//”開頭
多行注釋:以 "/*" 開頭 ,"*/" 結(jié)尾,比如:

文檔注釋:"/**"開頭,"*/"結(jié)尾(一般用不上,了解一下就行)

張小飛:“那,每句代碼都要寫注釋嗎?”
諸小亮:“這倒不用,給你一個建議:寫代碼前,先寫注釋,把自己的思路用文字先寫下來”
“這我明白,就像寫作文前,先寫大綱一樣,對吧”
“是這個道理,你理解的還挺快”諸小亮夸贊道
4. 了解一下的——常量
諸小亮:“來,我們接著聊常量”
常量:固定值,不能改變,比如:12345678,這些數(shù)字在現(xiàn)實中都是固定的,8就是8,無法改變
張小飛:“怎么就無法改變呢?看我一刀下去,不就成倆 0 了?”

“那以后就能用這倆 0 來代替 8 這個數(shù)字了嗎?”諸小亮微笑的問道
“這個,嗯。。。。?!?/span>
“你這一刀只是把這張紙分成了兩份,但是數(shù)字 8 仍然是 8 ,所以說它是常量”諸小亮解釋道
“那,按照您在這么說,3.14 也是常量了?”張小飛問道
“是的,Java中的常量分為以下幾種:”

“小飛啊,這些都能看懂吧”
“可以看懂,就是不知道怎么用”
“放心,之后的代碼中會經(jīng)常用到,目前只是了解一下”
5. 非常重要的——變量
1. 總述
諸小亮:“師弟,下面要介紹變量了,這是非常重要的,一定要仔細聽”
張小飛:“師兄放心”
“變量:顧名思義,就是可以改變的值,比如:在數(shù)學(xué)中定義 x=3,y=4,z=x+y (xyz都是變量)”
再 Java 中定義變量,格式:數(shù)據(jù)類型 變量名 = 變量值;(注意:末尾有分號)
“師兄,這個數(shù)據(jù)類型是????”
“就是字面上的意思,比如:3是整數(shù)類型,3.14是小數(shù)類型(也叫浮點數(shù)類型)”
“原來如此,明白”
“Java中定義了 8 種基本數(shù)據(jù)類型,比如:”

良久,“師兄,我有 3 個問題,第一:byte、short、int、long都是整數(shù)類型,為什么有4種?”
諸小亮:“之所以分成4個類型,是因為每個類型占用的內(nèi)存空間不同,來先給你普及一下基礎(chǔ)知識:”
? ?
?
“編寫代碼時會設(shè)置大量的變量,在程序運行時每個變量都會占用一定的內(nèi)存,但是內(nèi)存是比較珍貴的資源,如果用較小的空間就能夠達到目的最好,比如:如果只做 100 以內(nèi)的計算,那么使用 byte 類型就好”
“原來如此,第二個問題:浮點數(shù) 和 布爾類型我能理解,不過這個字符,為什么取值也是數(shù)字呢”
“這個,之后的寫代碼時會給你詳細解釋的”
“好吧,那么第三:這些類型該如何使用呢?”
“這就是我們接下來要做的事情了”
2. 整數(shù)類型
“小飛啊,整數(shù)是我們工作中做常用的,所以一定要好好聽,來,我們修改這個 Demo.java 文件”

注意:我們定義 byte b = 3; 這個 b 就是標(biāo)識符
“師兄,您剛才還不是說不能用 aa、bb這樣的標(biāo)識符嗎?現(xiàn)在。。。。?!睆埿★w無語到
“這個......嗯.....,其實這個 b 是 byte 的意思,師弟,這不是工作,不用這么嚴格”
“好吧。。。。?!?/span>
“接著,我們在命令行對它進行編譯:”

“師兄,您這樣做的目的是???”
“馬上你就知道了,我們繼續(xù)修改:“

“你再次編譯看看”
“師兄,這是不是編譯失敗了?”張小飛說到

諸小亮:“是的,我給你解釋一下”
在 Java 中,默認所有整數(shù)都是 int 類型,所以 300 被當(dāng)成 int 類型
代碼中,要把 300 賦值給一個 byte 類型的變量,而 byte 的取值范圍是 -128~127 ,根本容不下300,所以提示:“從 int 轉(zhuǎn)換到 byte 可能會有損失”
而 byte b = 3; 雖然 3 也被當(dāng)作 int,但 3 在 byte 的范圍內(nèi),編譯時會自動轉(zhuǎn)為 byte 類型
張小飛:“原來是這樣,我明白了,這表示之后使用整數(shù)時要先確定它具體是哪個類型”
“沒錯,我們繼續(xù)定義其他整數(shù)類型”諸小亮說到

“師弟,注意,上圖的代碼編譯,還會報錯:”

張小飛疑惑的問道:“這不對吧, 之前說過 long 類型的最大值是 2 的63次方 - 1,而 12345678900 遠遠小于這個值,為什么還報錯呢?”
諸小亮:“原因:在 Java 中默認認為所有整數(shù)都是 int 類型,報錯是因為 12345678900 超過了 int 的最大值”
“原來是這樣,那該怎么辦呢?”
“很簡單,只需要在12345678900后面加上一個 L 就行了,表示這個數(shù)字是 long 類型,比如:”

“你再次編譯試試看”
張小飛:“確實,修改后再次編譯,不報錯了:“

3. 自動類型提升
“師兄,自動類型提示是什么意思?”
“用代碼演示一下你就明白啦,還是修改之前的代碼:”

結(jié)果:

張小飛:“3+4=7,這不是很正常嘛”
諸小亮:“你仔細看,代碼中,x是 byte 類型,y是 int 類型,為什么 x+y 的值 可以賦給 z 呢?”
“是啊,為什么?”張小飛恍然大悟道
“這就是自動類型提升:不同類型數(shù)據(jù)計算時,小類型會自動轉(zhuǎn)換為大類型”
“你的意思是,x +y 時,自動把 x 從 byte 升級到了 int 類型?”
“是的,你理解的完全正確,不過要注意一點:同類型計算也可能出問題,比如:”
結(jié)果:

張小飛:“這是為什么呢?a 、b 、c 都是 short 類型啊”
諸小亮:“因為:int 是 java 中整數(shù)的默認類型,小類型(byte、short)的計算同樣會自動類型提升”
“那,兩個 int 類型做計算時,會自動提升為 long 類型?”
“這個倒是不會,記?。?/span>int 是 java 中整數(shù)的默認類型”
“好吧,int 是 java 中整數(shù)的默認類型,這個你說了很多遍了,我記住了”
“很好,孺子可教也”
4. 強制類型轉(zhuǎn)換
1. 演示
諸小亮:“師弟,你能參考自動類型提升,來解釋一下什么是 強制類型轉(zhuǎn)換 嗎?”
張小飛思索了一下,說到:“自動類型提升是小類型升級為大類型,強制類型轉(zhuǎn)換是大類型轉(zhuǎn)為小類型?”
“沒錯,是這個意思,我們先看一段代碼:”
“師兄,這段代碼有問題吧”
“哦?你來說說看是什么問題”諸小亮好奇的問道
“x 是 byte 類型,y 是 int 類型,按照剛才的說法: x+y 時 x 會自動提升為 int 類型,所以 x+y 的結(jié)果是 int 類型 ,把一個 int 類型的值賦給 byte 類型的 z 不是有問題嗎?如果我記得沒錯的話,編譯的時候應(yīng)該會提示:從 int 轉(zhuǎn)換到 byte 可能會有損失”張小飛回答到
“厲害,你說的一點兒都不錯,這是編譯的結(jié)果:”

“但是,如果告訴你有一種方法可以讓上面的代碼賦值成功呢?你想不想知道?”
“師兄,你就別賣關(guān)子了,直接說吧”
“我們繼續(xù)修改代碼:”

“這樣編譯就不會報錯,程序也正常運行:”

張小飛:“原來這就是強制類型轉(zhuǎn)換啊,很簡單嘛”
諸小亮:“是的,確實很簡單,但是如果使用不當(dāng),也會造成一些問題的”
“什么問題?”
“來,我們再次修改代碼,這次修改 y = 400”

“你看看最終輸出的結(jié)果是多少”
“這個。。。,怎么會是一個負數(shù)?”

“因為:x + y =403,這是一個 int 類型的數(shù)值,強制轉(zhuǎn)換為 byte 后,精度缺失造成的”
“精度缺失???”張小飛疑惑的問道
“是的,想要徹底明白這個問題,我們需要先聊一聊二進制”
“。。。。。。二進制又是什么鬼”
2. 神奇的—二進制
諸小亮:“二進制:本質(zhì)是一種計數(shù)方式,也是計算機語言”
計數(shù)方式:十進制(滿10進1),60進制(60s=1m),7進制(7天=1周)
二進制比較特殊,是滿 2 進 1,比如:1+1=10,10+1=11,11+1=100
注意:二進制都由 0 和 1 組成
張小飛:“這個計數(shù)方式我能理解,不過它也是計算機語言?”
“是的,在計算機中,一切都是以二進制形式存在的,不同的 01 組合代表不同的含義,使用不同的 01 組合代表世間萬物,所以就有虛擬世界這一說法”
比如:01010代表:我,01011代表:你,0000000111111代表:他
注意:這里只是舉個例子,并不是說 ‘我’ 在計算機中對應(yīng)的就是:'01010'
張小飛:“有點兒意思,按照您的說法,數(shù)字在計算機中也是用二進制表示”
諸小亮:“沒錯”
“師兄,可否讓我見識一下,一個十進制數(shù)字用二進制怎么表示?”
“當(dāng)然可以,網(wǎng)上有很多進制轉(zhuǎn)換的工具,比如:https://tool.oschina.net/hexconvert/”

“這個,10 具體是怎么變?yōu)?1010 的呢?”張小飛問道
“轉(zhuǎn)換的方法不是重點,重點是:int a = 10;,那它的二進制實際是:00000000 00000000 00000000 00001010”
良久,張小飛:“我明白了,因為 a 是 int 類型,占 4 字節(jié) ,也就是占 32 個位對吧”
“是的,其實把一個數(shù)字換位二進制分兩步:”
1. 利用上面的網(wǎng)址轉(zhuǎn)換為二進制
2. 在左側(cè)補0,具體補多少個0,就看它是那種類型的
張小飛:“我來試一下,如果 byte b = 3 ,那么它的二進制是:00000011”
“完全正確”
“師兄,如果是一個負數(shù)呢?您提供的網(wǎng)站工具是這樣顯示的:”

“上面給的不對,負數(shù)的二進制稍微麻煩一些,以 byte b = -10 為例,分為 3 步:”
1. 先獲取它的正數(shù)的二進制,是:00001010,這稱之為:-10 的原碼
2. 將原碼的每一位做取反,得到反碼:11110101
3. 將反碼+1:11110110,這就是 -10 的二進制
“師弟,其實這個負數(shù)的轉(zhuǎn)換,了解一下就行了,實際時候用的并不是很多”
“好的,不過到現(xiàn)在我也不明白,這個跟 精度缺失 有什么關(guān)系呢?”
3. 最終解惑
諸小亮:“我們回憶一下:x + y = 403,是 int 類型,占 4 字節(jié)(32位),那么它的二進制。。。”
“403 的二進制是:00000000 00000000 00000001 10010011” 張小飛搶著說到
“沒錯,而我們的代碼是把 int 類型轉(zhuǎn)為 byte 類型”
byte 類型占 1 個字節(jié),int 類型 轉(zhuǎn)換為 byte,就要丟掉3個字節(jié),這就是精度缺失
“丟掉 3 個字節(jié),那不是變成 00000000 了嗎?這應(yīng)該是 10 進制中的 0 啊”張小飛說到
“錯了,應(yīng)該是丟掉左側(cè)的3個字節(jié),那么剩下:10010011,而它的十進制就是 -109 ”諸小亮回復(fù)道
“原來如此”
“師弟,在告訴你一個結(jié)論:計算機中,二進制最左側(cè)以 1 開頭的都是負數(shù)”
“明白?。?!”
5. 小數(shù)類型
諸小亮:“我們接著看小數(shù)類型,也就是浮點數(shù)類型,這個就比較簡單了”
float 和 double,double的精度更高一些
精度:精確程度,小數(shù)越多,精確成度就越高
“但是,實際開發(fā)中一般不用 float ,為了數(shù)據(jù)的準確性,都使用double,比如:”

編譯會報錯:

張小飛:“讓我猜一猜,報錯的原因是: Java 中默認認為所有小數(shù)都是 double 類型”
“是的,如果要用 float 類型,需要在末尾加上一個 f,比如:”

6. 布爾和字符類型
諸小亮:“布爾類型很簡單,定義一個boolean類型的變量如下:”

張小飛:“這個很容易理解,我疑惑的是 char 類型為什么是數(shù)字?”
“先看一段代碼,然后再給你解釋”

結(jié)果:

“師兄,說實話,這個代碼和輸出結(jié)果,讓我更加的迷糊了”
“來,我給你解釋一下:”
計算機能理解的語言是:二進制,而人類的語言是:abc、你我他、0-9、!@#$%等,
為了方便的跟計算機溝通,先輩們使用二進制跟人類語言做了個映射
比如:01100001---->a,01100010---->b
這種映射關(guān)系稱為:ASCII編碼表
“就是用二進制來表示世間萬物嘛,這個我懂,但是沒想到前輩們竟讓做了一張表出來,這個表是什么樣子的?”
“來看下面的這張圖:”

“從圖中可以看出,01100001轉(zhuǎn)換為 10 進制就是 97,也就是字母 a,正因為這樣,所以 char 類型的值可以是數(shù)字也可以是字符”
“那為什么代碼中兩個輸出,一個是數(shù)字,一個是字符呢?”張小飛接著問
“上面代碼的執(zhí)行過程是這樣的:”
計算機先把 97 轉(zhuǎn)換為二進制:01100001
執(zhí)行 println 時,因為 c 是 char 類型,所以就通過ASCII編碼表找到了a,并輸出
執(zhí)行:c2 + 2 時,因為類型不同,c2先做類型提升(轉(zhuǎn)換成97),所以最終結(jié)果是 int 類型的 99
張小飛:“原來如此,這下我就明白了”
諸小亮:“那么我們接著說,接下來是。。。?!?/span>
“停停停,師兄,這都中午了,該歇一歇了吧,肚子都餓扁了”
“哦?沒想到時間過的這么快,那好吧,走吃飯去,回來后你好好練一練”
“???不會吧,正所‘食飽思眠欲’,吃過飯后不應(yīng)該睡一覺嗎?”
“大白天睡什么覺,浪費生命”
“這你就不懂了,睡覺是一種藝術(shù),睡不好是你糟塌了,沒聽過嗎?‘少睡一分鐘,就缺少60秒的幸?!?/span>
“行行行,我說不過你,不過下午可不會再給你時間練習(xí)的”
“放心吧,這也沒多少東西,早就記牢了”