1. Java 編譯器
順帶一提,您會不只一次聽到:Java 相較於其他語言的無可爭辯的優勢——就是跨平台性。這到底是什麼?我們從頭說起。
重點是:電腦只能執行最基本的指令。
對狗來說,有「靠腳邊」、「握手」等口令,牠一聽到就會做出重要動作。對電腦而言,這類口令的角色由數字扮演:每條指令都被編碼成某個數字(也稱為機器碼)。
把程式寫成一串數字非常困難,因此人們發明了程式語言與編譯器。這樣的語言一方面讓人好懂,另一方面也讓編譯器能理解。編譯器是一種特殊的程式,會把以程式語言撰寫的程式文本,轉成一組機器碼。
通常工程師先用程式語言寫程式,接著啟動編譯器,編譯器會根據工程師所寫的原始碼檔案,產生一個機器碼檔案——也就是最終(已編譯)的程式。
- 以 C++ 撰寫的程式
-
編譯器
- 由機器 碼組成的程式
最後得到的程式可以立刻在電腦上執行。這種做法的缺點在於,所產生的機器碼與處理器與作業系統緊密相依。為 Windows 編譯的程式,無法在搭載 Android 的手機上運作。
如果你為 Android 撰寫程式,那麼在 Windows 作業系統上它不會啟動!
但 Java 採取了更創新的做法。
- 以 Java 撰寫的程式
-
Java 編譯器
- 程式, 由 特殊 代碼(位元組碼)組成
-
Java VM
- 程式, 由 機器 碼組成
Java 編譯器不會把所有類別編成一個機器碼程式。它改為逐一編譯每個類別,且目標不是機器碼,而是特殊的中間碼(位元組碼)。真正轉成機器碼是在程式執行時完成。
那麼,在程式啟動時,誰來把它編成機器碼呢?
為此有個特殊的程式,名為 JVM(Java Virtual Machine,Java 虛擬機器)。先啟動它,再啟動由位元組碼組成的程式;JVM 會在執行前,將所需的部分即時編譯成機器碼。
如果你的處理器很強大,支援更多的機器指令集,那麼在「第二次編譯」期間,生成的機器碼會針對你的處理器與作業系統最佳化。這也是為什麼 Java 有時會比 C++ 更快;C++ 會在一開始就直接編成機器碼,只能使用處理器最常見的指令。
2. 編譯時的常見錯誤
目前速度與最佳化先不重要,更重要的是編譯器會檢查你的程式是否有錯。它會檢查語法與正確性,只要發現哪怕一個小錯誤,就不會讓它通過。
錯誤範例:
你嘗試把數字指定給一個只能存放文字的變數。
String userName = 42; // 哎呀!這樣不行。
編譯器會立刻指出型別不相容:Cannot implicitly convert type 'int' to 'string'。
另一個例子——在呼叫 println 時打錯字:
System.out.printline("你好!"); // 方法名稱拼錯了
編譯器會說:「沒有這個方法——檢查語法!」
如何閱讀錯誤?
多數編譯器會提示錯誤所在的位置,甚至有時會給出修正建議。不要害怕錯誤:每一次錯誤,都是邁向開悟、打倒你內心「Boss」的一步。
3. 註解
想像一下:你正在撰寫一個複雜的程式。一切運作良好,你——天才!但一個月後你再打開同一份程式碼,卻……看不懂了。這裡兩行,那裡一個奇怪的變數。腦中只剩:「這絕對不是我寫的!」這時,註解就能救你。
註解就像課本邊角的備忘、或冰箱上的便條("啤酒,別喝,留到明早!")。編譯器會忽略它們,但人類相反。註解可以用來解釋程式碼的意圖、標記重要細節,甚至能「關掉」某些片段而不必刪除。
重要:沒有任何編譯器會讀你的註解;它們會被完全忽略!
單行註解
在 Java 中有兩種註解——單行與多行。單行註解以雙斜線 // 開頭並持續到行尾。凡是出現在 // 之後的內容,都被視為註解並且會被編譯器完全忽略。
範例:
System.out.println("哈囉,世界!"); // 這會在螢幕上印出問候語
這裡的 // 這會在螢幕上印出問候語 就是註解。如果某行程式碼的用途不明白,就這樣寫清楚吧!
再一個例子:
int x = 42; // 程式設計師的年齡值
也可以把單行註解寫在獨立行:
// 初始化使用者名稱的變數
String userName = "Vasya";
就像劇本中的台詞:註解會說明「為什麼要這樣做」。
多行註解
如果你有很多話要說、甚至是一個小故事?就用多行註解吧,它以 /* 開始、以 */ 結束。這兩個符號之間的內容都會被編譯器忽略,即便跨越多行也一樣。
範例:
/*
這裡我們把使用者名稱輸出到螢幕。
如果沒有名字,就寫上 "訪客"。
*/
System.out.println("請輸入您的姓名:");
或者這樣:
int age = 18; /* 新使用者的
初始年齡值 */
注意:不能把一個多行註解巢狀在另一個多行註解中。別試圖比編譯器更聰明——這行不通。
示意:
| 類型 | 語法 | 範例 |
|---|---|---|
| 單行 | |
|
| 多行 | |
|
4. 實務範例
「關掉」一行程式碼:
有時你會暫時不想執行某個程式片段。註解正好派上用場:
// System.out.println("暫時不需要的文字");
那行還在,但編譯器「看不見」它。
TODO 與 FIXME 標記
工程師也是人,有時需要提醒自己:這段程式還沒完成,或這裡有 bug。常見的寫法是:
// TODO: 檢查是否為空輸入
// FIXME: 這個函式對總和的計算不正確
許多編輯器與 IDE 甚至會特別標示這些字!
工程師的幽默
// 我不為這段程式負責。有人強迫我違背意願寫的。
// 親愛的,我_來自_未來!請原諒這段程式。
// 如果我再看到這種東西,我就得開始帶武器上班了。
// 如果這個條件哪天真的成立,請打電話 xxx-xxx-xxx 告訴我,必有重謝。
// 親愛的工程師:
//
// 當你「最佳化」完這個子程式
// 並意識到這其實是個大錯誤時,
// 請在下面把計數器加一,作為對下一位同仁的警告:
//
// kolichestvo_chasov_potrachennykh_zdes’ = 42
// 我開始寫這段時,只有上帝和我知道我在做什麼。
// 現在只剩上帝知道了
// 有時我覺得編譯器忽略了我所有的註解
// 我把我所有的程式與工作都獻給我的妻子 Darlin,
// 當這東西上線時,她得養活我、我們的三個孩子和狗。
沒錯,註解可以很有趣。畢竟寫它們的是活生生的人。
GO TO FULL VERSION