# 程式的架構與進入點 程式的架構與進入點: 要了解程式的結構,首先要知道程式的進入點,也就是「main()方法」(也可以稱作main()函數)。main()方法,和C語言與其它的程式語言一樣,它是Java程式的「進入點」(Entry point),也就是說,程式的執行順序是由「進入點」開始的。可以把main()方法比喻成「劇院的入口」,一旦執行程式,Java就會優先找到main()方法,從該行開始執行程式,而不是程式的第一行喔。 在Java中作為進入點的main()函數,語法如下: class Test{ public static void main(String[ ] args){ System.out.println("Hello Java~~"); } } main()方法的身體{ }之內放的是主程式碼,用這邊的比喻來說,就是「演出劇本」。不過作為範例,這邊的主程式碼只寫了一行:在螢幕上顯示「Hello Java~~」文字。 由於Java是很強調物件導向的程式語言,因此就算是作為程式進入點的main()函數,也必需被包裹在一個類別的{ }之內,例如這邊的Test類別。也就是說,Java程式的最小單位是類別(class),即使是程式的進入點也必需被包裹在一個類別的{ }之內。這樣做有很多好處,其中一個最明顯的優點是,可避免因為較難掌控全域變數的值的變化而產生的bug,因為我們已經把每個程式碼的組成單元都宣告成class,讓每個class各自獨立了(以class的大括號{ }區隔開來)。 我們再進一步說明。「進入點」的意思就是說,真正的主程式碼是在main()方法的{ }區塊裡面,其他不屬於這個區塊的程式碼,都算是「前置動作」或者「故事背景」或者「角色設定」,只有main()方法的{ }區塊裡面,才是真正「演出劇本」的地方。所以,有可能在main()方法的{ }區塊裡面只有少量的程式碼,而其他區塊,由於做了很多定義類別、宣告變數、定義函數(撰寫演算法)、定義介面 … 的事情,所以反而會有大量的程式碼。 用比喻來說,就像一部戲劇,有豐富的故事背景、華麗的人設、漂亮的場地佈置,但真正演出時卻不到十分鐘就演完了。雖然短,但它確實是一部完整的戲劇,可能也還是很好看,所以不能因為main()方法的{ }區塊裡面的程式碼比較少,來判斷程式的好壞。 就像現在鋼骨結構的房子,基本的鋼骨結構都是在工廠中製作,再運輸到工地現場把它們拼裝起來,所以你會覺得鋼骨結構的房子怎麼都蓋的那麼快,因為其過程就像是拼裝已經組好大部分模組的樂高(LEGO)積木一樣,模組已經事先花時間製作完成了,你只要把這些模組在現場拼裝起來,就完成了。 由於我們已經把每個物件的角色都分配好了,所以main(){ } 函數內的程式碼變得相當精簡。 大量應用函數(以及自訂的函數)、物件 這就是所謂的「結構化程式設計」 Arduino也是這樣 這邊有個小訣竅,雖然main()函數(程式的進入點)是對編譯器而言的,不過當我們想要了解一個程式在做什麼的時候,也可以像編譯器一樣先從main()函數的{ }區塊開始讀起。如果這個程式的註解做得好,不用看定義就能知道每個函數的作用,如果有必要再搭配去看其他的部分,有可能比老實的從頭到尾一行一行的讀,能更快、更容易了解這個程式的作用。 知道了程式的「進入點」的功用後,我們再來深入分析它的語法: public static void main(String[ ] args) { 主程式碼(演出劇本) } 首先,作為進入點的main()方法它的權限一定要是public,這樣它才可以直接被外界所呼叫(使用),也就是權限要public才可以讓觀眾進來看戲。而且,由於它必須要有「不需經過實體化產生物件的步驟,就能使用」的特性,所以它必定要加上static修飾字,也就是說main()必須是個靜態方法。 最後,void表示main()方法不需要回傳任何值,因為它本來就只是個入口,即使有回傳值也沒意義。不過要注意,不是每個程式語言的進入點都不需要回傳值(void),像C++或C語言就規定作為進入點的main()函數的回傳值型態必須要是int而不是void,這就要看你用的是哪種程式語言了。 至於在main()方法的()括號內的參數「String[ ] args」,叫做「命令列引數(Command line argument)」,可以在程式執行時取得使用者指定的相關參數,不能留白,但絕大多數情況下照這樣寫就好了。而至於為什麼要這樣寫,怪里怪氣的感覺,解釋起來比較複雜,目前暫時先把它當作是人為強制規定的語法,背下來就好了。 還有一個要提醒的重點,就是在一個類別(class)中只能有一個main()方法,不可以有兩個進入點。 static:靜態的,靜態表示在程式剛開始執行前,就要把這些東西載入到記憶體。所以main()函數必須是static,不然記憶體中沒有main()函數的程式碼,是要執行什麼? String[ ] args ,身為程式進入點的main可以接受字串陣列當做參數,這也是JVM定義好的,String[ ] 表示字串陣列,args是為這些字串陣列取的變數名稱,當然也可以寫 main(String[ ] aaa)。 args:arguments 編譯(complier)式語言才需要有進入點。 Python或JavaScript等直譯式語言,不會經過complier的動作,會直接由上往下,一列一列的將程式執行下去,所以不需要寫一個main()之類的進入點。 * 註:關於命令列引數 前面提到,main()函數是作為程式進入點的函數,不過它的引數「String[ ] args」有個特別的名稱,稱為「命令列引數」(Command-Line Arguments),我們發現它是個名為args的字串陣列。「命令列引數」可以用來控制「命令提示字元」,讓我們可以使用命令提示字元來呼叫(執行)程式的.exe執行檔,如下圖: 在古早DOS(Disk Operating System,譯作「磁碟作業系統」)作業系統的時代(約1980年代頭 ~ 1990年代尾,當時Windows還未普及),command-line argument可是非常重要的。其實現在的Windows系統也一直有把DOS系統保留下來,只不過改稱為「命令提示字元」,沒用過的朋友可以在開始功能表的搜尋列搜尋來用看看。DOS是純文字的介面,滑鼠沒什麼用處,要執行任何操作都要輸入指令才行。 JAVA也內建定義了一些特殊的命列列引數,讓我們可以在呼叫程式(也就是執行main()函數)的同時啟動一些內建的功能。我們可以在「命令提示字元」視窗中輸入「javac」,系統會列出一張表,讓我們知道main()函數在接收了不同的引數之後,會對應去做什麼事情,即顯示每個引數所代表的意義,就是下面這張表: 不過,我們通常會直接在編譯好的.exe執行檔上雙擊滑鼠左鍵以執行程式,若非專業人員,很少用到這種舊式的方式來執行程式了,也很少需要main()函數幫我們做些什麼特別的事情。所以若對DOS根本沒頭緒的朋友(年齡大多都小於30歲),當然很難理解命令列引數的作用。 所以,若想深入學習的讀者再自己去研究,或者真的遇上了再去了解就好;若不想深入了解的讀者就單純的把main()函數當作程式的進入點就好了,不去深入研究命令列引數也沒有多大影響。
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up