Java 基本語法 -...
Transcript of Java 基本語法 -...
E
Java 基本語法
E-1 Java 簡介 E-2 E-2 Java 程式初體驗 E-21 E-3 變數、常數與資料型態 E-36 E-4 運算子 E-53 E-5 流程控制 E-68
E-2
E-1 Java 簡介
E-1-1 Java 的前世今生
Java 語言的起源
在 1990 年,Sun Microsystem 公司進行了一個名為 Green 的專案,此專
案的目的,是希望運用 C++撰寫嵌入式軟體,用以控制具備簡單控制晶片
的消費性電子產品,如:PDA(個人數位助理)、遙控器、微波爐、烤箱…等。
讓這些電子產品能夠提供更多、更聰明的功能,方便使用者操作,且 Green
專案的開發人員,還希望開發出的嵌入式軟體,能具備良好的可移植性,
讓同樣的程式,可以很方便地在不同控制晶片上執行。
但專案人員後來卻發現,C++並不符合要求,因此,決定重新開發一個
適合開發跨平台嵌入式軟體的語言,它就是 Java 的前身 – OAK。在開發
OAK 時,專案人員拿掉了 C++那些可能造成系統錯誤的機制,如:指標、
運算子的過載以及資源的直接參考。並且將記體體管理的機制,直接放進
語言中,讓程式設計師不必費心去煩惱記憶體配置的問題。不過,必須請
您注意的是,Java 並不是新版本的 C++,雖然 Java 的確受到 C++相當大的
影響,且兩者的語法也相當類似。
當 Java 遇上 WWW
WWW 開始發燒,大家開始體認到網際網路所帶來的無限商機,此時,
OAK 技術也接近了純熟階段。Green 專案的開發人員,認為 OAK 的跨平台
特性,很適合運用在網際網路上開發應用程式。因此,決定將 OAK 正式更
名為 Java,並於 1996 年 1 月發表了第一個 Java 編譯器。
E-3
Java
基本語法 E
E-1-2 Java 的執行原理
位元組碼(ByteCode)
Java 編譯程式輸出的程式碼稱為位元組碼(ByteCode),但並不是可執行
的程式碼,而是必須由虛擬機器(Java Virtual Machine,簡稱 JVM)解譯才能
執行。所以當 Java 要在不同系統(晶片)上執行時,程式設計師只需要修改
JVM,解決每種系統不同的差異性。這樣那些原先已經編譯為位元組碼的
Java 程式,便可不需要修改,即可在不同系統上正常執行。
Java 虛擬機器(Java Virtual Machine,JVM)
JVM 為用來解譯及執行位元組碼的解譯器,目前 JVM 存在的形式,可
能在軟體中,如:Java 程式開發工具 JDK 程式、微軟的 IE 或是網景的
Navigator 瀏覽器…等,另一種形式是將 JVM 製作在硬體的晶片上,此種
晶片稱為 Java chip。
即時編譯器(Just in time,JIT)
JVM 負責解譯及執行位元碼,但之前須先經過 Java 的即時編譯器,將
程式編譯成位元碼的動作。JIT 編譯器是 Java 2 所新增的編譯器,可直接將
Java 程式,編譯為進行編譯機器的機械碼。
E-1-3 小心錯誤的觀念
在介紹『物件導向』之前,首先要澄清兩個重要的觀念:
Java 不等於物件導向,它只是支援物件導向機制的程式語言
物件導向觀念是一種程式設計的思考方式
E-4
這兩個觀念為何要在學習 Java 的一開始就立即提出來呢?最主要是因
為太多人把物件導向跟 Java 混為一談,更甚者認為 Java 就是物件導向。探
究造成這種情形的原因,不外乎是因為 Java 的風行,搶走了物件導向的鋒
頭,因此才會發生誤把馮京當馬涼的現象。
真相呢?….
Java 是一個純物件導向語言,因為它的裡裡外外都是以物件導向觀念設
計的。當用物件導向觀念進行程式設計時,運用支援物件導向機制的程式
語言進行設計,更能夠加快程式開發的速度,並適切地表達出系統的設計。
另一個廣為人知的物件導向程式語言為 C++。
E-1-4 物件導向觀念與 Java
在講解物件導向觀念與 Java 前,必須先告訴各位,程式語言與程式設
計思維間的不同。
Java 是一種物件導向語言,所謂的物件導向是指一種程式設計的觀
念,而 Java 則是依據這種觀念設計出來的語言。當然還有其他類型的語言,
如:程序式語言,當然這類語言就不具備物件導向觀念。
當程式設計師設計電腦系統時,我們可以說,都是在利用電腦模擬真
實世界的某些行為。在模擬的過程裡,思考如何模擬真實世界的觀念,就
是所謂的程式設計思維。
舉個例子來說吧!請各位回想一下到圖書館借書的情形。現在絕大部
份圖書館的還書、借書作業,都是運用電腦完成;但是在電腦尚未普及的
時候,圖書館的借/還書作業則是全部以人工完成。換句話說,圖書館的圖
書管理程式,就是在做當年沒有電腦時,以人工完成的借/還書作業,因此,
電腦程式所做的,就是模擬真實世界裡的借/還書作業。
E-5
Java
基本語法 E
而物件導向觀念的用途,就在幫助程式設計師如何思考,並設計出一
個圖書管理程式來模擬真實世界的人工借/還書作業,以完成電腦化的圖書
管理作業。
物件導向思維 V.S. Java
上面說明了設計思維與電腦系統的關係,用了設計思維完成電腦系統
(程式)的設計與分析,相當於建築師畫好了設計圖,接下來的問題就是要如
何施工。
『工欲善其事,必先利其器』,當用了物件導向思維設計系統,當然
要用具備物件導向觀念的程式建構系統囉!因為物件導向程式語言是符合
物件導向思維的程式開發工具,雖然運用物件導向觀念設計程式,並不必
然要用物件導向程式語言撰寫系統。但是若不用物件導向程式語言建構系
統,將造成許多物件導向觀念的不易完成,因為這些語言根本不支援這種
機制。所以,在這裡我們為您釐清了物件導向觀念與物件導向程式的關係,
一個是設計的觀念,一個是完成設計的工具。
而 Java 則是目前物件導向程式語言中較廣為人所接受的,當用物件導
向觀念完成現實世界的分析,設計出電腦系統的藍圖後,接下來就要用 Java
這類物件導向語言,實現設計藍圖。
E-1-5 物件導向觀念入門
物件導向的四個基本觀念
前面一直在說明物件導向觀念與程式設計及物件導向程式的關係,在
這一節裡,則要開始正式介紹物件導向觀念。
E-6
物件導向觀念其實是一個很直覺的思維模式,因為它分析真實世界的
角度,較其他設計觀念更接近人類直覺觀點。它的本質在於用物件導向觀
念尋找、分析出現實世界的物件與物件間的關係,然後運用程式語言模擬
這些現實世界的物件,最後完成電腦系統的建構。物件導向觀念是架構在
以下四個基本觀念之上,它們是:
物件
類別
訊息
繼承
在下面的幾個小節裡,將把物件導向與現實世界間,做一個比較,並
讓您瞭解物件、類別、訊息、繼承這四個基本觀念,與真實世界間的關係。
物件
物件相當是現實世界的生物,比如:老虎、貓、狗…這些動物,在物
件導向觀念裡,這些動物都是物件。再廣泛一點來說,其實物件就是東西,
也就是我們周遭一切有形或者無形的事物。
那物件導向觀念是如何描述、模擬這些現實世界的物體呢?回答這個
問題之前,先來看看如何描述現實世界的物體。想要描述現實世界中的物
體時,大致會描述物體的特性。物體的特性,可分為靜態與動態兩種。舉
例來說,物體的名字、顏色、長寬…等就是靜態特性,在物件導向觀念來
說,這些靜態特性就是物件的屬性(Attribute),在 Java 中又稱為欄位(Field)。
所以,貓是該種生物的名稱,也就是該種生物的屬性之一。東西如果是活
的,它就有動作,而這些動作就是物體的動態特性,在物件導向裡稱為物
件的方法(Method)或者操作(Operation),比如:貓叫就是貓這種生物的方法。
E-7
Java
基本語法 E
類別
類別可以看成一堆物件的特性描述,也就是對某種物件的抽象描述。
就像我們知道貓是一種動物,你家養的小花是一隻貓。如果寫一個模擬貓
的程式時,程式內一定有一個貓類別,裡面描述了貓的特性,比如:貓的
叫聲、貓有四隻腳、腳上有爪子、貓有名字…等。當要用這個程式模擬你
家的小花時,就要用貓類別建立一隻名叫小花的貓物件。因此,您可以把
類別想成是建立物件的模子,當在程式中建立一個物件時,就必須以類別
作為模子,產生一個物件,而這個物件就具有這個類別的屬性與方法(屬性
與方法,合稱為類別的成員)。所以,某一個類別(貓類別)可以建立許多物
件(貓),就像有一個模子可以做出好多個零件一樣。
訊息
訊息在物件導向系統中扮演了相當重要的角色,而訊息在物件導向模
擬的電腦系統裡,就相當於真實世界裡人所說的話,藉由訊息的傳遞,觸
動物件的方法(這裡絕不可說成類別的方法,因為類別只是一個模子,完成
系統功能的是物件),然後產生動作,完成系統功能。
前面講的類別與物件的屬性,以及下面的繼承,這都是物件導向技術
模擬真實世界中物體的靜態部份,訊息則屬於動態描述的部份。而訊息運
作時,跟物件的方法有密不可分的關係。當發送一個訊息給物件後,物件
必須依據接收到的訊息做回應,這個回應動作就是物件的方法。這就好像
您按下了視窗中的某一個按鈕,視窗將會有所回應,比如:最小化視窗或
者關閉視窗。
繼承
我們常常聽到別人說,物件導向技術可以提高軟體的再利用,其背後
的主要功臣之一就是繼承(Inheritance)觀念。繼承的觀念可以站在兩種角度
來看它。一是分類的觀念,二是遺傳的觀念。
E-8
分類是人類慣用的邏輯觀念,將性質相似的東西歸為一類,可以方便
於瞭解與管理現實世界的事物。比如在生物學裡,將所有的生物分門別類
地歸納在生物分類裡,低層次的分類將具備高層次分類的特性。
動物界 家貓種貓屬貓科
靈長目
偶蹄目
食肉目
硬骨魚綱
鳥綱
哺乳綱脊索動物門
軟體動物門
. . . . . . . . . .
. . . . .
犬科. . .
豹屬. . .
. . .生物
植物界
人種人屬人科
也有許多書以遺傳的觀念講解繼承的觀念,就如俗語所說的『龍生龍,
鳳生鳳,老鼠生的兒子會打洞』,下一代具備上一代的某些特性。在物件
導向觀念裡,就是衍生類別具有基礎類別的特性。
從上面兩個常用於講解繼承觀念的角度來看,不論是生物分類或者是
遺傳,都圍繞著一個主軸 - 特性的繼承。對應到物件導向的繼承觀念裡,
就是所謂的特性繼承。
在程式裡,繼承又扮演什麼樣的角色呢?我們來講講一個模擬貓的動
物模擬程式。貓是一種哺乳類動物,所以,程式裡貓類別將繼承於哺乳類
動物類別。因此,貓將具有哺乳類動物類別裡描述哺乳類動物的特性,如:
會哺乳。但是貓類別除了繼承哺乳類的特性外,仍有其它的特性,要不然
所有的哺乳類動物不就都一模一樣了嗎?所以,在貓類別裡,將會再定義
貓特有的特性,如:會抓老鼠。
從上面的描述裡,仍看不出應用繼承的好處在哪?但如果有一天,要
擴充程式增加狗的模擬,再建立一個狗類別。此時,好處就浮現了,因為
狗也是哺乳類動物,所以狗類別也應該繼承於哺乳類動物類別。此時,就
不需描述狗類別中具有的哺乳類動物特性,只要將狗類別繼承於哺乳類動
E-9
Java
基本語法 E
物類別即可。因此,在貓、狗類別裡,都不需要描述它們所共同具備的會
哺乳特性,這就再利用了定義哺乳類動物類別的程式碼。同樣地,狗類別
的特性,如:會看家,則必須在狗類別裡定義。
您還不懂嗎?
接受一個新的思考方式,是需要時間與耐心的,這一節的目的,只希
望讀者先大概知道,什麼是物件導向、基本觀念又有哪些。以附錄有限的
篇幅,我們僅能大致介紹 Java 的基本語法,有關物件導向觀念的部份,並
無法介紹。讀者想要深入,還請參考其他相關的 Java 程式設計書籍。
E-1-6 JDK 的下載與安裝
JDK
JDK 的全名是 Java Development Kit,是由 IBM 公司所開發,供程式設
計師用於開發 Java 程式的工具程式,目前為 1.6 版。由於 Java 2 有別於
Java,因此,JDK v1.6 又被稱為 Java 2 SDK(Java 2 Software Development
Kit)。使用 JDK 時,您必須先從網路下載,並完成安裝,這將在稍後提到。
JDK 內所提供的工具,在本書中將用到 javac 與 java 這兩個程式。javac
是 Java 的編譯器(Complier),用於將 Java 程式編譯為位元組檔,java 則是
Java 的解譯器(Interpreter),用於執行 Java 程式的位元組碼。
Java 2 SDK 的下載
Java 2 SDK 的安裝,在本書的適用版本為 1.4.2 以上,因此只需在此版
本之後皆可以執行,SDK 最新版本為第 6 版。在安裝前,您必須從下面這
個網址中,完成安裝檔案的下載。
http://java.sun.com/javase/downloads/index.jsp
E-10
進入下載網頁,請依照您使用的電腦作業系統與語言,按下合適之 SDK
安裝檔的超連結,如您下載時是不同的版本時,其下載網址與安裝步驟可
能會有些許不同,不過原則上步驟是一樣的,讀者按照網站指示皆可完成
下載與安裝。本版本下載過程說明如下:
接著,將出現選擇作業系統版本及語言視窗,請選取完後按下
CONTINUE 按鈕。
按下
按下下載 SDK安裝程式
E-11
Java
基本語法 E
最後,按下 Download Selected with Sun Download Manager 即可執行下
載:
Java 2 SDK 的安裝
完成 Java 2 SDK 安裝檔案的下載後,在安裝檔案上快速按兩下滑鼠左
鍵,便可開始安裝。
連按兩下執行
按下
E-12
進入安裝畫面後,直接按下 Next 按鈕。
在這個畫面將可設定 Java 2 SDK 的安裝資料夾,預設為 C:\Program Files\Java\jre6,若欲更改安裝位置時,可按下 Browse 按鈕,以瀏覽方式
點選磁碟內的資料夾。完成設定後,便可按下 Next 按鈕。
下一個動作即可開始正式安裝 Java 2 SDK。
按下
按下
E-13
Java
基本語法 E
完成安裝後,將出現下面的畫面,請按下 Finish 按鈕。
E-1-7 程式開發環境的使用
Java 2 SDK 的開發環境,必須在 MS-DOS 模式下,接下來的敘述,將
為您介紹 MS-DOS 的操作。
什麼是 Dos
Dos 是早期的電腦作業系統,在 Dos 作業系統下,電腦的使用可不像
現在這樣,可以用滑鼠點一點就完成操作。必須全靠鍵盤,將指令鍵入電
腦。而在 MS-Dos 下開發 Java 程式時,您必須瞭解一些基本的 Dos 環境操
作。因此,在開發的過程中,您需要使用一些簡單的 Dos 指令,以下將先
為您介紹如何進入 MS-Dos 環境,接著,再介紹一些常用的 Dos 指令。
MS-Dos 環境的開啟
欲進入 Dos 環境時,請執行 [開始 /所有程式/附屬應用程式/命令提示
字 元 ] 指 令 。 進 入 命 令 提 示 字 元 模 式 後 , 預 設 資 料 夾 位 置 為
C:\WINDOWS\,畫面如下:
E-14
Dos 環境的路徑觀念–資料夾
資料夾在 Dos 模式下亦稱之為目錄,將以樹狀圖的方式,分類儲存電
腦磁碟內的檔案。您可以開啟檔案總管,左半部視窗將以樹狀圖的方式顯
示磁碟內的資料夾。
在指令列中執行指令時,指令列前將會顯示目前指令所動作的資料夾
位置,這個位置稱之為目前資料夾。下圖的指令列,將顯示目前資料夾的
位置為 C:\WINDOWS。
E-15
Java
基本語法 E
絕對路徑與相對路徑
在講解如何在指令列中,切換目前資料夾的位置之前,必須先介紹絕
對路徑與相對路徑的觀念。以絕對路徑表達磁碟位置時,將從電腦磁碟開
始描述。下面的語法,將表達出 C 碟 XMLEx 資料夾下 AppE 子資料夾
Hello_Java 資料夾之位置。
C:\XMLEX\AppE\Hello_Java
在電腦系統中,對任何一個資料夾位置而言,此表達方式所代表的資
料夾位置均相同,故稱為絕對路徑。
相對路徑則是以指令列目前資料夾的位置為參考點,表達磁碟路徑的
方式。假若目前的指令列位置在 C:\XMLEx,則該資料夾位置,即可運用
以下的相對路徑表達出『C:\XMLEx\AppE\Hello_Java』的位置。
AppE\Hello_Java
由於上述相對路徑是以 C:\XMLEx 為參考點,若目前資料夾位置在 C
碟時,XMLEx\Hello_Java 並不能代表『C:\XMLEx\AppE\Hello_Java』位置。
Dos 指令的基本語法
Dos 指令的基本語法如下:
指令名稱 /參數
完成指令鍵入後,需按下 鍵執行。下面的指令將在 C 碟的
XMLEx 資料夾下,執行資料夾內檔案與資料夾名稱的查詢動作。
C:\XMLEx>dir /w
此外,由於 Dos 環境中無法鍵入中文,因此檔案或是存放檔案的資料
夾名稱,建議不要使用中文命名。
E-16
磁碟切換指令
在 Dos 模式下,若欲切換至電腦的其他磁碟時,需在指令列中鍵入『磁
碟代號:』指令,例如:欲切換至 D 碟時,則鍵入『D:』。
資料夾切換指令
在 Dos 模式下,若欲切換至其他資料夾下時,需在指令列中運用 cd 指
令,語法如下:
cd 資料夾路徑
在前面曾經提到,資料夾路徑的指定方法可分為相對路徑與絕對路徑
兩種。以下將舉例說明 cd 指令的使用方式,假若在 C:\中有一個如下圖所
示的資料夾路徑,且指令列目前資料夾的位置在 C:\。
下表為各種資料夾位置切換指令的範例與說明。
切換指令 說明 cd c:\XMLEx 以絕對路徑的方式,將資料夾位置切換至 C:\XMLEx 資料
夾。 cd c:\XMLEx\AppE 以絕對路徑的方式,將資料夾位置切換至 C:\XMLEx\AppE
資料夾。 cd XMLEx 以相對路徑的方式,將資料夾位置切換至 C:\XMLEx 資料
夾。 cd XMLEx\AppE 以相對路徑的方式,將資料夾位置切換至 C:\XMLEx\AppE
資料夾。
E-17
Java
基本語法 E
若以相對路徑方式切換資料夾位置時,還有一些代表特殊位置的符
號,說明於下表:
符號 說明 \ 切 換 到 目 前 資 料 夾 所 在 磁 碟 的 根 資 料 夾 。 若 目 前 資 料 夾 位 置為
c:\XMLEx\AppE,則『cd \』指令,將把目前資料夾位置切換至 c:\。 .. 目前資料夾位置的上一層資料夾。若目前資料夾位置為 c:\XMLEx\AppE,
則『cd ..』指令,將把目前資料夾位置切換至 c:\XMLEx。
當資料夾名稱中有空白或者長度超過 8 個字元時,則必須使用『"』符
號,標示資料夾名稱。以下敘述將把目前資料夾,切換至 C:\My Documents。
cd "C:\My Documents"
資料夾查詢指令
資料夾查詢指令用於查詢目前所在路徑下,所有檔案與資料夾的名
稱、大小、建立日期…等資料,該指令的語法如下:
dir /參數
常用的參數說明於下表:
符號 說明 w 列出目前資料夾下,所有資料夾與檔案的名稱。 p 以一頁一頁的方式顯示目前資料夾下,所有資料夾與檔案的資料,包含名
稱、大小、最後儲存時間…等
下圖中,將在 JDK 的安裝資料夾下(C:\Program Files\Java\jdk1.6.0_12),
以 dir 指令列出該資料夾下,所有資料夾與檔案的清單。
E-18
列出檔案內容
若您想直接在 Dos 模式下顯示某檔案的內容時,可以使用 type 指令,
語法如下:
type 檔案名稱
下圖中,將列出 C 碟根資料夾下 Autoexec.bat 檔的內容。
E-1-8 Java 環境設定與批次檔的應用
什麼是批次檔
批次檔(.bat)是一個純文字檔,可以將數個 Dos 指令鍵入該檔中。執行
該檔時,便會可執行該檔中的 Dos 指令。由於該檔的格式為純文字檔,因
E-19
Java
基本語法 E
此,可直接用 Windows 提供的 NotePad 建立該檔,只要在儲存檔案時,以.bat
做為副檔名即可。
利用批次檔執行 Java 環境設定
在開發 Java 程式時,必須執行環境設定的動作,對於這些動作,建立
為批次檔,在每次開啟 Dos 模式視窗時,便自動執行,省去手動設定的麻
煩。Java 開發環境的設定主要有以下兩個,功能說明如下:
PATH 參數 - 讓 Dos 在您使用 Java 編譯程式時,知道到那裡尋找
編譯程式。
CLASSPATH 參數 - 讓 Java 編譯器進行編譯時,能夠讀取到已完
成編譯之類別的位元碼(bytecode)。
若在 E-1-6 節中,將 JDK 安裝於預設的 JDK1.6.0 資料夾時,則必須以
下面的 Dos 指令,設定 Dos 的 PATH 系統參數,如下所示:
SET PATH=c:\PROGRAM FILES\Java\jdk1.6.0_12\BIN\
而以下指令,則將設定 CLASSPATH 系統參數,在尋找位元組碼時,
要一併搜尋目前資料夾的位置。
SET CLASSPATH=.;
請開啟 NotePad,並將上述兩列環境設定指令,鍵入檔案中,最後並儲
存為 Java.bat 檔。
E-20
此外,由於每次編譯、執行程式的指令都相同,所以,筆者建議您應
該在批次檔中,加入 Dos 的 Doskey 指令,這樣便可用鍵盤的 、 鍵,
找出曾經使用的 Dos 指令。加入 Doskey 指令後,Java.bat 檔將如下圖所示。
完成建立的批次檔儲存於光碟的 XMLEx 資料夾的 ch01 子資料夾下。
E-1-9 Java 的編譯/執行指令
在 MS-DOS 環境下,是以鍵盤鍵入指令的方式,操作環境。在本書中,
開發 Java 程式時,所需使用的編譯、執行程式之指令說明如下:
javac 編譯程式
javac 指令將把完成撰寫的 Java 程式,編譯為 JVM 認得的位元組碼,
使用語法如下:
javac 程式名稱.java
下圖為編譯 E-2-3 節 Hello_Java.java 程式時,於 Dos 指令列中鍵入的編
譯指令。
當程式完成編譯後,將產生副檔名為 .class 的位元組碼檔。
E-21
Java
基本語法 E
java 執行程式
將 Java 程式編譯為位元組碼檔後,欲執行程式時,需使用 java 程式,
其語法如下:
C:\資料夾路徑>java 程式名稱
下圖為完成 Hello_Java 程式的編譯後,運用 java 指令執行該程式的敘
述。
E-2 Java 程式初體驗
E-2-1 在學程式之前
給完全不懂程式的人
有一次朋友這樣問我,什麼叫程式?說真的還有點不知道該如何對完
全不懂程式的人,解釋什麼叫做程式?幾經思考歸納出程式的四個特徵:
程式是人與電腦溝通的語言
程式是由特定語法與保留字,構成一列一列的程式敘述。(保留字與
語法的意義,請參考 E-2-2 節的說明)
程式是一列一列執行的
程式的執行,從進入點開始,原則上是由上而下、由左而右執行的
執行結果
E-22
學習程式的不二法門
學習程式最好的方法,就是把範例程式親自敲進電腦裡,然後 Run 一
下,如果敲錯了,導致編譯程式顯示錯誤訊息,這樣更好,反反覆覆多看
幾次,相信一下子就可以把程式學好了。
E-2-2 名詞解釋
下面是本書中常用的名詞與用語解釋:
程式敘述 - 程式的片段(只有一列或者更少),稱之為程式敘述。
保留字 - 程式中定義的特定用字,也可以說是保留給程式使用的
字,如:if、main、void…這些都是保留字。
語法 - 所謂的語法,就是指程式的保留字,以及一些特定符號,按
照一定方式排列,這個排列方式稱之為語法。
程式區段 - 相對於敘述,程式區段則是由至少一列程式所組成的程
式片段。
E-2-3 Hello Java!程式
您的第一個程式–Hello Java!
在上一章大略地介紹程式及物件導向的基本觀念後,接下來,將寫一
支小小的程式,向 Java 說聲 Hello。透過這個程式的撰寫,將協助讀者建
立撰寫物件導向程式的基本概念。 檔名:Hello_Java.java 001 /*
002 範例檔名:Hello_Java.java
003 版權擁有人:郭尚君
004 */
E-23
Java
基本語法 E
005 006 import java.lang.*; //引用套件
007
008 public class Hello_Java
009 {
010 public static void main(String args[])
011 {
012 Printer My_Printer = new Printer();
013 //依據 Printer 類別建立 My_Printer 物件
014 My_Printer.Hello(); //呼叫 My_Printer 物件的方法
015 }
016 }
017
018 class Printer //定義 Printer 類別
019 {
020 private int Serial_Number; //定義 Printer 類別的屬性
021
022 public void Hello() //定義 Printer 類別的方法
023 {
024 System.out.println("Hello Java!"); //印出 Hello Java!
025 }
026 }
E-2-4 程式的建立與編譯
程式的建立
若您可使用任何可將檔案儲存為純文字檔的文字編輯工具,撰寫 Java
程式,例如:Windows 的 Notepad 就是筆者常用的文字編輯器。下圖為將
Hello_Java 範例程式鍵入 Notepad 後的畫面。
程式進入點
E-24
欲儲存檔案時,副檔名需命名為 .java。
程式的編譯
完成程式的儲存後,接著就要將程式編譯為位元組碼。欲進行 Java 程
式的編譯時,需進入 Dos 模式 (請參考 E-1-7 節的說明 )。以下為編譯
Hello_Java.java 檔的敘述(假設您將程式儲存於 C:\My Documents 資料夾
下)。
副檔名需為.java
E-25
Java
基本語法 E
C:\My Documents>javac Hello_Java.java
在編譯過程中,若程式有錯誤,則將產生錯誤訊息,您可以按照錯誤
訊息所告知,錯誤發生的位置與原因,進行程式除錯。假若您在 Hello_Java
程式的第 12 列結尾少打了一個『;』號,在編譯時,將出現如下的錯誤訊
息。
程式的執行
完成編譯後,便可運用以下指令執行程式。
C:\My Documents>java Hello_Java
執行結果如下圖所示。
E-2-5 範例程式概觀
Hello_Java 範例程式的目的,主要在示範 Java 如何模擬真實世界的印
表機。在範例程式裡,將建立一個名為 Printer 的類別,這個類別具有一個
將資料輸出到螢幕中的方法,就好像真實世界的印表機,將資料印出到紙
張上一樣。
E-26
大小寫有別
在 Java 裡,英文字母的大小寫是不一樣的,比如:Hello 並不等於 hello,
所以在撰寫程式時要注意兩者的差異。
程式結尾符號–『;』
在 Java 裡,每一列程式敘述都以『;』符號結尾。
Hello_Java 的重點
在這個程式裡,還有七個比較重要的地方需要講解:
1. 程式註解的使用 2. import 敘述 3. 類別的建立 4. 程式進入點 5. 建立物件 6. 訊息 - 呼叫物件的方法 7. 資料的輸出
下面各節將分別講解這些地方。
E-2-6 程式註解的使用
什麼是程式註解? 001 /*
002 範例檔名:Hello_Java.java
003 版權擁有人:郭尚君
004 */
這是 Hello_Java.java 範例的前四列,這四列是程式的註解。程式註解
並不是給電腦看的,而是給人看的,註解本身跟程式的運作是沒有關係的。
E-27
Java
基本語法 E
當程式編譯到註解時,將直接略過完全不會去理會它。註解的主要功能在
於協助人閱讀程式時,能更容易地瞭解程式的內容,因為程式畢竟是電腦
使用的語言,人是很難一下子就看得懂。而在 Java 中,註解的方式有兩種,
分別是區段註解與單行註解,分述於下。
區段註解
以下敘述將介紹如何在 Java 程式中,標示一整段註解文字,標示語法
如下:
/* 註解文字
*/
以『/*』與『*/』包含說明程式的註解文字,在『/*』與『*/』間不論
有幾列,當程式編譯時,都將略過。所以,不論在『/*』與『*/』之間寫了
什麼,對程式本身的執行並不會造成任何影響。在 Hello_Java.java 的前四
列,便是一段區段註解。
但是,每次註解不論長短,都要用『/*』與『*/』將註解文字包含起來,
似乎很麻煩。所以,Java 又提供了另一種單行註解方式,請看下一段的說
明。
單行註解
單行註解是 Java 所提供,另一個較簡潔的註解標示方式,其語法如下:
程式碼… //註解文字
//註解文字
這類註解適用於簡短的程式說明,像範例程式的程式內容註解就是採
用這種方式。因為它們都只是一些簡短的註解說明,所以用單行註解的方
E-28
式比較方便。與區段註解不同的是,單行註解的效力,僅止於『//』符號所
在該列以後的部份,下一列如果要再鍵入註解文字,就必須運用另一個『//』
符號。在 Hello_Java.java 的第 14 列中,便運用單行註解,說明程式敘述的
意義。
014 My_Printer.Hello(); //呼叫 My_Printer 物件的方法
養成好習慣…
在程式裡加入程式註解,是一個程式設計者必須建立的習慣,這樣不
只是幫助別人瞭解您的程式,更是幫助自己,在過了許久後,再回頭看自
己撰寫的程式時,能夠快速地回憶起當時撰寫程式的邏輯,所以在程式裡
多加註解只有好處,不會有壞處。試想如果本書中的範例程式,都沒有註
解時,您覺得您可以很容易就看懂程式嗎?
E-2-7 import 敘述
在大部份的 Java 程式中,您一定會看到與 Hello_Java.java 程式第 6 行
相同的 import 敘述,這一行用於引用套件(Package)。
006 import java.lang.*; //引用套件
什麼是套件
在 Java 中,所謂的套件(Package)是由數個與某種特定用途相關的類別
組合而成,因此,您可將套件當成一個包含許多類別的類別庫。這樣說起
來,套件其實就有點像程序式語言的函數庫,只不過,Java 的套件中,並
不提供函數,而是提供一個個具有特定功能的類別或介面,如:提供檔案
存取功能 FileReader 類別、FileWriter 類別…等。
對於第一次學程式的初學者,上面的敘述好像太生硬了,讓人不太能
夠想像到底套件是啥?您可以想像套件,就像現在提供插卡功能的電子翻
E-29
Java
基本語法 E
譯機。當插入遊戲卡時,翻譯機就多了遊戲可讓您玩。當插入多國會話卡
時,翻譯機就可以提供多國會話。而套件就是 Java 提供給您,在寫程式時,
許多具有特定功能的『卡』,當需要時,只要將套件『插』進程式即可。
引用套件的 Import 敘述
當在 Java 想要引用某個套件時,一般都會運用 import 敘述,將套件引
用進程式。不過,在這邊要強調,使用 import 敘述引用套件,只是方便您
在程式內,運用該套件的類別時,不需要再特別指出類別的所屬套件。
import A 套件 .B 子套件 .*; //引用 A 套件下所有類別
X 類別 //X 類別為 A 套件中的類別
所以若您未使用 import 敘述引用套件時,還可以運用以下語法,使用
A 套件之 B 子套件的 X 類別。
A 套件 .B 子套件 .X 類別
在 Java 的 JDK 中,提供了許多套件,它們是由提供 JDK 的廠商所建
立。善用套件中的類別,對於撰寫程式是相當重要的。套件的來源除了 JDK
外,還有許多廠商會撰寫提供特定功能的套件,銷售給程式設計師,如:
用於設計 3D 繪圖程式的套件。
預設引用的 java.lang 套件
java.lang 套件是所有 Java 程式撰寫時,都必須運用的套件,裡面包含
了許多常用類別,如:System、String、Object、Integer…等,因此,Java
預設每個程式都會引用 java.lang 套件,使用這些類別時,即便不使用 import
敘述引用 java.lang 套件,也不需指定這些類別的所屬套件。因此,
Hello_Java.java 第 6 列的 import 敘述是多餘的,可以直接拿掉。
E-30
但是並不是每個套件都被設定為預設引用,當欲使用的套件沒有透過
import 敘述引用時,就必須指出該類別的所屬套件。否則,當您編譯程式
時,將產生不能解析的錯誤訊息,如下所示。
ReadFile.java:9: cannot resolve symbol
symbol : class FileReader
location: class ReadFile
FileReader fr = new FileReader("ReadData.txt");
ReadFile.java:9: cannot resolve symbol
symbol : class FileReader
location: class ReadFile
FileReader fr = new FileReader("ReadData.txt");
2 errors
E-2-8 類別的建立
用類別模擬印表機
在 Hello_Java 裡,建立了一個 Printer(印表機)類別,以模擬真實世界的
印表機。這個類別的功能(方法),就是在螢幕上印出 Hello Java!字樣,以下
是建立 Printer 類別的程式片段:
018 class Printer //定義 Printer 類別
019 {
020 private int Serial_Number; //定義 Printer 類別的屬性
021
022 public void Hello() //定義 Printer 類別的方法
023 {
024 System.out.println("Hello Java!"); //印出 Hello Java!
025 }
026 }
無法解析的錯誤訊息
E-31
Java
基本語法 E
建立 Printer 類別的敘述,主要由以下三個部份所組成:
定義類別
定義屬性
定義方法
分述於下面三小節。
定義類別
定義一個類別的語法如下:
class 類別名稱 //開始類別定義,並定義類別名稱
{ 程式區段; //定義類別的屬性與方法
} //完成類別定義
所以在 Hello Java 裡,將利用同樣語法定義 Printer 類別:
018 class Printer //定義 Printer 類別
019 {
020…025 程式區段; //在程式區段中定義類別的屬性與方法
026 } //完成 Printer 類別的定義
在兩個{}符號中間的程式區段裡,將定義這個類別的屬性與方法。
定義屬性
前面講過,物件導向對真實世界的物件模擬,是靠分析物件的屬性與
方法而達成的,所以,在定義該類物件之類別的內容時,主要工作為定義
所具備的屬性與方法,其中屬性就是該類物件的特性或者性質。
屬性的定義語法
當定義一個屬性時,必須在類別內定義,並告訴 Java 這個屬性的資料
E-32
型態為何?如此定義後,當程式執行時,電腦才知道要分配多少記憶體以
儲存這個屬性。其語法如下:
修飾詞 資料型態 屬性名稱;
以 Printer 類別所模擬的印表機來說,其特性有廠牌、型號、序號…等。
在 Hello_Java.java 範例,為了簡化問題,在 Printer 類別中,僅採用宣告一
個序號屬性(第 20 列,Serial_Number),儲存印表機的序號資料。
020 private int Serial_Number; //定義 Printer 類別的屬性
第 20 列的 private 修飾詞用於定義屬性的存取特性。在 Java 中類別的
屬性或者方法(兩者又合稱為類別的成員),都有四種存取特性的分級,它們
分別是 public、protect、private、無修飾詞。所謂的存取控制,就是定義其
他物件是否可以直接存取物件成員的機制。不過,這個部分在附錄內將不
再深究,若您有興趣請參考 Java 相關書籍。
此外,屬性的定義敘述,必須放在類別定義內,因此,Serial_Number
屬性的定義將放在 Printer 類別的定義內。
018 class Printer //定義 Printer 類別
019 {
020 private int Serial_Number; //定義 Printer 類別的屬性
021..025 … …
026 } //完成 Printer 類別的定義
E-2-9 定義方法
方法的定義語法
欲定義一個方法時,與屬性一樣都必須在類別內定義,並告訴 Java 這
個方法的回傳值型態為何?如此定義後,當程式執行時,電腦才知道要分
配多少記憶體來儲存這個屬性,其語法如下:
E-33
Java
基本語法 E
修飾詞 資料型態 方法名稱()
{ 方法的內容
}
在 Printer 類別裡,有一個方法,這個方法將會在螢幕上輸出『Hello
Java!』字串。在程式範例裡,於第 22 列到第 25 列,定義了一個名為 Hello
的方法。在第 22 列裡,我們看到了存取控制的 public 修飾詞,它代表 Printer
類別的 Hello 方法,可以讓其他類別的物件直接呼叫,有關方法的存取控
制修飾詞,在附錄內將不深入說明,若您有興趣請參考 Java 相關書籍。 018 class Printer //定義 Printer 類別
019 {
020…021
022 public void Hello() //定義 Printer 類別的方法
023 {
024 System.out.println("Hello Java!"); //印出 Hello Java!
025 }
026 }
E-2-10 程式進入點
主程式類別
有些 Java 書中,也將主程式類別稱為公用類別(Public Class),因為主程
式類別必須宣告為 public 型態,本書則習慣稱它為主程式類別,因為 Java
程式的進入點 – main()方法,宣告於這個類別中,有關 main()方法的說明
請參考 E-2-11 節的說明。
建立主程式類別時,有一個最重要的規定,那就是類別名稱需與此程
式的檔名相同,且一支程式中只能宣告一個主程式類別,也就是僅能有一
個存取控制等級定義為 public 的類別,主程式類別的宣告語法如下:
E-34
public class 類別名稱
{ 類別成員
}
在 Hello_Java.java 程式中,定義主程式類別的敘述如下: 008 public class Hello_Java
009 {
010…015 …程式區段
016 }
E-2-11 main()方法
所有程式都必須有一個程式的進入點,做為開始執行程式的位置。在
Java 程式中,主程式類別將擁有一個 main()方法,此方法即為 Java 程式的
進入點,而 Java 宣告程式進入點的語法如下:
public static void main(String args[])
{ 程式敘述;
……
}
在範例程式的第 10 列至第 15 列,將定義 Hello_Java 程式的 main()方
法,Hello_Java 程式的執行將從此方法開始。
010 public static void main(String args[])
011 {
012 Printer My_Printer = new Printer();
013 //依據 Printer 類別建立 My_Printer 物件
014 My_Printer.Hello(); //呼叫 My_Printer 物件的方法
015 }
由於 main()方法使用 static 修飾詞,所以它是一個類別方法,有關類別
方法的進一步說明,請參考 Java 相關書籍。
程式進入點
必須與程式的檔案名稱相同
E-35
Java
基本語法 E
E-2-12 建立物件
建立類別的目的就是為了要做為建立物件的樣版(Template,您可以把它
想成建立物件的模子),下面是利用類別建立物件的語法:
類別名稱 變數 = new 類別名稱( );
在 Hello_Java.java 範例程式的第 12 列,將利用 new 運算子,產生一個
Printer 物件。
012 Printer My_Printer = new Printer();
013 //依據 Printer 類別建立 My_Printer 物件
前面這句話,是值得您好好想一想的,Printer 不是類別嗎?這裡怎麼又
稱之為物件?其實這句話,說得詳細一點,應該是『My_Printer 是一個 Printer
類別的物件』。
E-2-13 訊息–呼叫物件的方法
在 E-1-5 節裡,曾經提到訊息的觀念,對應到程式的運作裡,訊息就是
呼叫物件的方法,呼叫語法如下:
物件 .方法名稱(引數); //呼叫物件的方法
在範例程式中,並沒傳任何資料給方法(My_Printer 物件的方法),因此,
呼叫時,括號內為空白。
010 public static void main(String args[])
011 {
012…013 ……
014 My_Printer.Hello(); //呼叫 My_Printer 物件的方法
015 }
至於在呼叫方法時,傳入引數的方式,將在 E-3-8 節呼叫 System 物件
println()方法時看到。
E-36
E-2-14 資料的輸出
在 Java 中,欲將資料輸出至螢幕時,必須呼叫 java.lang 套件中,System
類別內 out 物件的 println()方法,語法如下:
System.out.println(欲輸出的資料);
欲輸出字串時,則用『"』符號標示欲輸出的內容。在 Hello_Java 範例
中,Printer 類別的 Hello 方法內,便運用 println()方法將『Hello Java!』輸
出到電腦螢幕中(第 24 列)。 022 public void Hello() //定義 Printer 類別的方法
023 {
024 System.out.println("Hello Java!"); //印出 Hello Java!
025 }
您也可用擬人化的觀點來看 println()方法的運作,程式設計師好像將欲
輸出的字串,丟給 println()方法,由該方法將資料輸出到螢幕上顯示。
E-3 變數、常數與資料型態
E-3-1 變數與常數
什麼是常數
簡單來說,在程式中,常數(Constant)用於代表某個不會變動的資料,
就像『1』代表數值 1,『2.1』代表數值 2.1。在程式的執行過程中,它們
的值並不會改變。在 Java 中,共有數值、字串以及字元三類常數。下面是
一些數值常數。
123
10.5
E-37
Java
基本語法 E
-100.5
-25
在程式中,欲表示一段字串常數時,字串前後必須使用『"』標示。下
面是一段字串常數。
"I am Julianno!"
在程式中,欲表示一個字元常數時,字元前後必須使用『 '』標示。下
面為代表 A 字元的字元常數。
' A'
什麼是變數
所謂的變數(Variable)就是程式中變動的資料,在程式中,通常以一個
名稱來代表某個變數,下面是一個例子。
X = 1;
上述的敘述中,其含意為設定 X 等於(=)1。其中 X 就是一個變數,1
是一個常數。X 在程式的執行過程中,其所代表的值是可以被改變的,只
要程式中有敘述更改了它。舉例來說,當程式後來又執行了以下敘述後,
則 X 所儲存的值就是 2,不再是 1。
X = 2;
若您還是不太瞭解上述說明的含意,您就乾脆將變數想成是一個盒
子,在這個盒子裡,可以裝入資料。當程式需要使用資料時,再從盒子裡
取出來。
自訂常數
除了 Java 原來就規定的常數外,您還可以在程式中自行定義常數。例
如:將 PI 宣告為一個代表圓周率(3.14)的常數,則在程式的執行過程中,
E-38
PI 就相當於 3.14 數值,且不可被更改。有關自訂常數的方法,將於 E-3-9
節做進一步的說明。
E-3-2 變數
變數的宣告語法
在 Java 中,若欲使用某變數時,必須經過變數宣告的動作,語法如下:
資料型別 變數名稱;
若同時欲宣告一個以上的相同資料型態之變數時,可運用『 ,』符號,
將變數名稱隔開。
資料型別 變數名稱 1, 變數名稱 2, …;
以下語法將宣告一個型別為整數(int),名稱為 A 的變數。
int A;
下面的語法將同時宣告 A、B 為整數變數。
int A, B;
在 Java 中,並不限定宣告變數的位置,您可以在需要使用變數時,才
即時宣告。
變數名稱的限制
在宣告變數時,對於變數名稱的命名有以下的限制。
不能與 Java 所使用的保留字相同,如:您不能宣告一個名為 for 的
變數,因為 for 是 Java 中,迴圈敘述所使用的保留字。
變數名稱可利用英文字母、數字以及除了『 .』點以外的標點符號所
組成。
E-39
Java
基本語法 E
在同一個變數的可見範圍中,變數名稱必須是唯一的。不過,在 Java
中,英文有大小寫的區別,換言之,a 變數與 A 變數,將代表不同
的變數。
變數字首避免使用底線(_)與金錢符號($),以免被誤認為系統變數。
以下是一些錯誤的變數名稱:
錯誤一:
int i.a = 10; //不可使用「 .」符號
錯誤二:
int A = 10;
System.out.println("A =" + a); //由於變數名稱英文字母大小寫有別,僅宣告 A 沒有宣告 a
錯誤三:
int $A = 10; //易被誤認為系統變數
為何要宣告變數的型別
為何在宣告變數時,必須先宣告這個變數的資料型別呢?這是因為不
同的資料型別,儲存在電腦的記憶體中時,需要的記憶體空間大小並不相
同。當程式執行到變數宣告敘述時,程式便會在電腦的記憶體中,配置一
塊空間,用於儲存設定給這個變數的資料。這時到底要配置多大的空間,
就要視變數的資料型別而定。
所以,進行變數宣告時,必須指出這個變數的資料型別,電腦才知道
要配置多少空間給變數使用。至於 Java 中,各種資料型態所需要的儲存空
間,請參考 E-3-7 節的說明。
E-40
E-3-3 變數值的設定
變數值的設定語法
上述語法僅單純地宣告一個變數,且變數中,並未儲存任何值。若欲
將值設定給該變數時,必須運用『=』指派運算子,語法如下:
變數名稱 = 值;
以下敘述將把 100 指派給 A 變數。
A = 100;
宣告並起始變數值
在宣告變數的同時,您亦可同時起始變數值。以下敘述將在宣告 A 變
數的同時,將變數的起始值設為 100。
int A = 100;
E-3-4 變數的輸出
在 Java 中若欲輸出某個變數時,我們一樣可以運用 out 物件的 println()
與 print()方法,語法如下。
System.out.print(變數名稱);
System.out.println(變數名稱);
以下敘述將輸出 i 變數的值。
System.out.print(i); //輸出 i 變數值
若想要同時輸出變數值與字串時,則可以用『+』運算子,執行串連動
作,語法如下:
System.out.print(字串 + 變數名稱);
System.out.println(字串 + 變數名稱);
E-41
Java
基本語法 E
以下敘述將把 i 變數的值輸出在『i=』字串後。
System.out.print("i = " + i); //輸出 i 變數值
範例 E-1:輸出變數值
[執行結果] 1
i = 1
[程式內容] 檔名:PrintVAR.java 001 public class PrintVAR
002 {
003 public static void main(String args[])
004 {
005 int i = 1; //宣告變數並設定起始值
006
007 System.out.println(i); //輸出變數值
008 System.out.print("i = " + i);//用『+』運算子,串連字串與變數
009 }
010 }
E-3-5 給變數一個好名字–匈牙利命名法
在介紹匈牙利命名法前,我們先來看一下這個程式範例:
範例 E-2:計算圓面積
本範例中,將宣告 a、b、c 三個變數,並進行圓面積的計算。
[執行結果] Area is 78.5.
[程式內容] 檔名:CircleArea.java
程式進入點
E-42
001 public class CircleArea 002 {
003 public static void main(String args[])
004 {
005 double a,b,c;
006
007 a = 5.0; //設定圓半徑為 5
008 b = 3.14; //設定圓周率
009
010 c = b * a * a; //計算圓面積
011
012 System.out.println("Area is " + c + "."); //輸出結果
013 }
014 }
請把您的焦點放上述範例的第 7 列至第 10 列上,我們用 a、b、c 三個
變數,分別代表圓半徑、圓周率以及計算出的圓面積。如果今天程式裡沒
有註解的話,想要看程式範例裡的程式,恐怕有點難。但是如果把程式修
改如下:
003 public static void main(String args[])
004 {
005 double Radius,PI,Area;
006
007 Radius = 5.0; //設定圓半徑為 5
008 PI = 3.14; //設定圓周率
009
010 Area = PI * Radius * Radius; //計算圓面積
011
012 System.out.println("Area is " + Area + "."); //輸出結果
013 }
014 }
這次程式分別用 Radius、PI、Area,代表圓半徑、圓周率以及計算出的
圓面積,整個程式就算沒有程式註解,也可以大致看出,整個程式用於計
算圓面積。
程式進入點
E-43
Java
基本語法 E
然而,關於程式裡的變數名稱,有人主張不僅應該讓變數名稱易於瞭
解,還要讓該變數的資料型別一眼即可看出,這就是匈牙利命名法。因為
這可以幫助您在檢視程式的同時,就可以掌握等號兩邊的資料型別是否相
同,或者傳入方法(函數)的變數,其資料型別是否正確,以減低程式錯誤的
發生。
匈牙利命名法
匈牙利命名法要求程式設計師,在變數名稱前以特定字首註明該變數
的資料型別,如:一個用來儲存姓名的變數,其資料型別為 String,就應該
命名為 str_Name 或者 sName。因此,我們可以把 Cricle_Area 程式範例再次
修改如下:
003 public static void main(String args[])
004 {
005 double dRadius,dPI,dArea;
006
007 dRadius = 5.0; //設定圓半徑為 5
008 dPI = 3.14; //設定圓周率
009
010 dArea = dPI * dRadius * dRadius; //計算圓面積
011
012 System.out.println("Area is " + dArea + ".\n");
//輸出結果
013 }
014 }
這樣不但可看出變數的意義,連變數的資料型態都一清二楚。下表將
整理出,代表各資料型別冠於變數名稱前的字首:
資料型別 名稱 代表字首 short 短整數 sh int 整數 n long 長整數 l float 浮點數 f double 倍精度浮點數 d
E-44
資料型別 名稱 代表字首 char 字元 c String 字串 s boolean 布林數 b
運用匈牙利命名法的好處,在於能一目了然變數的型別,當然您也可
以不採納這種變數命名原則。但您至少要為變數取一個易於瞭解的名字,
如果都用一些 a、b、c…之類的名稱,日子一久恐怕連自己都看不懂。
E-3-6 變數的有效範圍
在 Java 裡,用『{ }』大括弧符號,表示某一段程式敘述為一個程式區
塊。當變數在該程式區塊宣告時,將只能在宣告該變數的程式區塊中被使
用,這個變數的有效範圍又稱 Scope。請看以下 Block.java 程式範例的示範。
範例 E-3:變數的有效範圍
本範例中,將說明 i、j 兩個變數宣告於程式的不同區塊時,兩變數將
有不同的變數有效範圍。
[執行結果] i = 1 j = 2
[程式內容] 檔名:Block.java 001 public class Block
002 {
003 public static void main(String args[])
004 {
005 int i = 1; //宣告變數並設定起始值
006 {
007 int j = 2; //宣告變數並設定起始值
008 System.out.println("i = " + i + " j = " + j);
程式進入點
E-45
Java
基本語法 E
//輸出變數值 009 }
010 //System.out.println("i = " + i + " j = " + j);
011 //如果上一行被執行會因為 j 未被宣告而發生錯誤
012 }
013 }
[程式說明]
本範例的重點,在於 i、j 這兩個變數。i 宣告於第 4 列至第 12 列的大
括弧中,所以在 4 至 12 列大括弧以內的範圍,都可以使用 i 變數,不論是
第 8 列或者第 10 列。但 j 就不一樣了,它宣告於第 6 列至第 9 列的程式區
塊中,只能在 6 至 9 列中使用。如果您將第 10 列的註解符號刪除,再重新
編譯程式時,將會發生 j 尚未被宣告的錯誤訊息。
E-3-7 Java 的資料型別
資料型別的種類
資料型別就是資料的類型,不同的資料類型,將有不同的特性,這些
特性包含這類型資料所能執行運算的動作,以及儲存此類資料的記憶體空
間大小,例如:對於兩個數值可以進行加減乘除,對於兩個字串可以進行
連結的運算。
在 Java 中,針對不同類型的資料,歸類出了八種型態,它們是 byte、
short、int、long、float、double、char、boolean,以下將把這些資料型態分
為四類加以介紹:
整數 – byte、short、int 與 long 屬於此類。
浮點數 – float 與 double 屬於此類。
字元 – char 屬於此類。
布林值 – boolean 屬於此類。
E-46
如何選擇欲使用的資料型別
那要怎樣選擇變數的資料型別呢?這就必須取決於您要儲存的資料類
型。如果型態是字元或布林值時,我們很容易地就能瞭解,變數需要宣告
為 char 或者 boolean。如果變數將儲存數值類型的資料時,則必須依據下面
的標準,來判斷欲使用的資料型別。
變數儲存的是整數還是浮點數
欲儲存數值的大小範圍
至於各種數值型別的數值大小範圍,請參考 E-3-2 節與 E-3-3 節的說明。
整數
在 Java 中,byte、short、int 與 long 這四種資料型別,用於表達整數資
料,並可表達正負數,如:-100。下表為各整數型別的說明。
型別 記憶體空間 名稱 可表達的數值範圍 byte 8 bit 位元組 從 -128 到 127 short 16 bit 短整數 從 -32,768 到 32,767 的整數 int 32 bit 整數 從 -2,147,483,648 到 2,147,483,647 的整數 long 64 bit 長整數 從 -9,223,372,036,854,775,808 到
9,223,372,036,854,775,807 的整數
若某整數資料欲強制使用 long 資料型別時,需在字尾加上 l 或 L 符號。
若在設定值前加 0x,則表示 16 進位數。以下敘述為整數型別變數的宣告,
與變數值的設定。
byte b = 127;
int i = 11111; short s = 32767; long a = 342768; long b = 342768L; //指定為長整數值 long c = 0x0a8c; //16 進位值的設定
E-47
Java
基本語法 E
浮點數
在 Java 中,float 與 double 這二種資料型別,用於表達具有小數點的數
值資料,並可表達正負數,如:-100.356。下表為各浮點數型別的說明。
型別 記憶體空間 名稱 可代表數值的範圍 float 32 bit 浮點數 從 1.4 e-45 到 3.4 e+38 double 64 bit 倍精度浮點數 從 4.9 e-324 到 1.7 e+308
在 Java 中,具有小數的數值,預設認定為 double 型別,若您欲強制指
定某數值為 float 型別時,必須在該數值後加上一個 f,例如:1.22f。以下
敘述將宣告浮點數值型別的變數,並完成變數值的設定。
float f = 1.22f;
double d = 1.22;
字元
用於儲存字元資料的型別為 char,由於 Java 的 char 型別使用全球文字
碼(Unicode),因此所佔記憶體空間為 16 位元。一般程式語言用於儲存字元
的字元型別,大多僅佔用 8 位元,所以無法表達出世界上使用的所有文字。
欲設定字元變數時,字元值前後必須以『 '』符號標示,以下敘述將『c』字
元設定給 c 變數。
char c = 'c';
布林值
型別為布林值的資料,其資料值僅有 true(真)與 false(假)兩種,常用於
程式流程的控制。在 Java 中,用於儲存布林值的型別為 boolean。以下敘
述是布林值型別變數的宣告,與變數值的設定方式。
boolean bo = false;
E-48
範例 E-4:宣告各種型別的變數與值的設定
[執行結果] b = 127
i = 128
s = 32767
l = 342768
f = 1.22
d = 1.22
c = c
bo = false
[程式內容] 檔名:DataType.java 001 public class DataType
002 {
003 public static void main(String args[])
004 {
005 byte b = 127; //宣告 byte 型別的變數, 並設定起始值為 127
006 int i = 128; //宣告 int 型別變數, 並設定起始值為 128
007 short s = 32767; //宣告 short 型別變數, 並設定起始值為 32767
008 long l = 342768L; //宣告 long 型別變數, 並設定起始值為 342768L
009
010 float f = 1.22f; //宣告 float 型別變數, 並設定起始值為 1.22f
011 double d = 1.22; //宣告 double 型別變數, 並設定起始值為 1.22
012
013 char c = 'c'; //宣告 char 型別變數, 並設定起始值為 c
014
015 boolean bo = false;//宣告 boolean 型別變數, 並設定起始值為 false
016
017 System.out.println("b = " + b);
018 System.out.println("i = " + i);
019 System.out.println("s = " + s);
020 System.out.println("l = " + l);
021 System.out.println("f = " + f);
022 System.out.println("d = " + d);
023 System.out.println("c = " + c);
024 System.out.println("bo = " + bo);
025 }
026 }
程式進入點
E-49
Java
基本語法 E
E-3-8 資料的輸出
print()與 println()方法
欲將資料輸出至螢幕時,通常使用 System.out 物件的 print()及 println()
方法,兩個方法的差異僅在於 println()方法將會把欲顯示的資料,顯示為一
行,並執行換行動作。但 print()方法輸出資料後,並不會換行,語法如下:
System.out.print (欲輸出的字串);
System.out.println (欲輸出的字串); //輸出後換行
在螢幕上輸出時,可使用『+』運算子,連接字串與變數,如下所示。
System.out.print("It is costed " + pen + " dollars.");
System.out.println("It is costed " + pen + " dollars.");
System 類別是由 java.lang 套件所提供,由於該套件為每個程式的預設
套件,所以並不需要使用 import 敘述引入。
範例 E-5:字串及變數的輸出
本範例利用 println()與 print()方法輸出字串及變數。
[執行結果] How much does it cost ?
It is costed 200 dollars.
[程式內容] 檔名:Printer.java 001 public class Printer
002 {
003 public static void main(String args[])
004 {
005 int pen = 200; //宣告變數及設定起始值
006
007 System.out.println("How much does it cost ?");
程式進入點
E-50
008 //輸出字串,並換行 009 System.out.print("It is costed " + pen + " dollars.");
010 //輸出字串及變數
011 }
012 }
特殊的字元常數–跳脫字元
當輸出資料時,可運用跳脫字元(Escape Sequence),控制資料的輸出。
下面是這些特殊字元的列表。
字元 作用 \n 換行(line feed) \r 回歸原位(carriage return) \t 定位鍵(tab) \b 倒退鍵 \f 換頁 \0 空字元 \” 雙引號 \’ 單引號 \\ 倒斜線
範例 E-6:跳脫字元的應用
在本範例中,將示範運用跳脫字元控制資料的輸出。
[執行結果] How are you?
You area writer.
Hi! Jack
This is a pencil.
Julianno Kuo
"twin quotation marks"
'single quotation marks'
\virgule\
E-51
Java
基本語法 E
[程式內容] 檔名:EscSeq.java 001 public class EscSeq
002 {
003 public static void main(String args[])
004 {
005 System.out.print("How are you?\n"); //換行
006 System.out.println("She is a writer.\r"+"You are");
//回歸原位
007 System.out.println("Hi!\t"+"Jack"); //定位鍵
008 System.out.println("This is a pen.\b"+"cil."); //倒退鍵
009 System.out.println("Julianno\0"+"Kuo"); //空字元
010 System.out.println("\"twin quotation marks\""); //雙引號
011 System.out.println("\'single quotation marks\'");
//單引號
012 System.out.print("\\virgule\\"); //倒斜線
013 }
014 }
E-3-9 自訂常數
前面提過常數,用於代表程式中不會變動的值。除了程式所定義的常
數外,亦可以自訂常數。
在程式執行的過程中,除了 Java 所定義表達特定數值、資料的常數外,
還有一些永遠不會變動,或者說是不應該變動的數值,比如:範例 E-2 圓
面積計算中的圓周率,它就是一個在程式執行過程中,不應改變的常數。
對於這一類的數值資料,便可運用自訂常數的方式,去定義一個常數名稱
代表這個數值,語法如下:
f inal 資料型態 常數名稱 = 常數數值;
當常數名稱經上述語法定義後,在程式編譯的時候,編譯器將會把程
式中所有使用到常數的地方,置換為設定給常數的數值。而運用自訂常數
有什麼好處呢?
程式進入點
E-52
用常數名稱代替數值較有意義,一目了然,如:以 PI 代替 3.14。
如果常數的值必須變動時,只要更改定義常數的敘述,而不需要
更改程式中,每一個使用到該常數的地方,方便程式的維護。
範例 E-7:自訂常數
本範例將改寫範例 E-2,將圓周率利用 final 關鍵字宣告成常數。
[執行結果] Area is 78.5
[程式內容] 檔名:CircleConst.java 001 public class CircleConst
002 {
003 public static void main(String args[])
004 {
005 final double PI=3.14; //定義 PI 為一個常數,其值為 3.14
006
007 double dRadius, dArea;
008
009 dRadius = 5.0; //設定圓半徑為 5
010
011 dArea = PI*dRadius*dRadius; //計算圓面積
012
013 System.out.println("Area is " + dArea); //輸出結果
014 }
015 }
[程式說明]
在範例程式的第 5 列裡,將 PI 宣告為常數,在程式的執行過程裡中,
PI 的值將永遠為 3.14。若希望增加計算的精確度,則只需要將第 5 列的 3.14
更改為更精確的數值即可,如:3.14159,並不需要到程式裡,更改每個用
到圓周率的運算式。
程式進入點
E-53
Java
基本語法 E
E-4 運算子
E-4-1 運算子與運算式
什麼是運算子
運算子為程式中用於執行計算動作的符號。在 Java 中,依照所執行的
計算動作,可以將運算子歸類如下:
算術運算子
比較運算子
邏輯運算子
字串運算子
指派運算子
各類運算子的說明,請參考接下來各小節的敘述。
運算式
由變數與運算子所構成,用於代表一連串計算動作的式子稱之為運算
式。
E-54
E-4-2 算術運算子
算術運算子用於執行加、減、乘、除…等數學運算,各算術運算子與
運用語法整理如下表:
運算子符號
名 稱
使用語法範例
當 A=7.0,B=2 時使用語法範例的 運算結果
+ 相加 A + B 7.0 + 2 = 9 - 相減 A – B 7.0 – 2 = 5 * 相乘 A * B 7.0 * 2 = 14 / 相除 A / B 7.0 / 2 = 3.5 % 取餘數 A MOD B 7.0 % 2 = 1
範例 E-8:算術運算子的使用
本範例將計算 A 等於 7,B 等於 2 時,運用各種運算子執行計算的結果。
[執行結果] 加法運算: A + B = 9.0
減法運算: A - B = 5.0
乘法運算: A * B = 14.0
除法運算: A / B = 3.5
取餘數 : A % B = 1.0
[程式內容] 檔名:Arith.java 001 public class Arith 002 { 003 public static void main(String args[]) 004 { 005 double A = 7.0; //設定 A、B 變數值
006 int B=2; 007 008 System.out.println("加法運算: A + B = " + (A + B)); 009 System.out.println("減法運算: A - B = " + (A - B)); 010 System.out.println("乘法運算: A * B = " + (A * B)); 011 System.out.println("除法運算: A / B = " + (A / B)); 012 System.out.println("取餘數 : A % B = " + (A % B));
程式進入點
E-55
Java
基本語法 E
013 } 014 }
用於串接字串的『+』運算子
算術運算子的加法運算子 - 『+』,除了執行數值的加法運算外,當
運用於字串時,還可串接兩字串,如:
str = "ABC" + "DEF";
上述運算式中,str 變數的值為『ABCDEF』。若您欲串接數值與字串
時,亦可使用『+』運算子。
str = "ABC" + 123;
上述運算式中,str 變數的值將為『ABC123』。
E-4-3 比較運算子
比較運算子用於比較兩數值間的大小關係,Java 的比較運算子整理如
下表:
運算子符號 名 稱 使用語法範例 當 A=7,B=2 時的計算結果 == 等於 A == B 假 > 大於 A > B 真 < 小於 A < B 假 >= 大於等於 A >= B 真 <= 小於等於 A <= B 假 != 不等於 A != B 真
當比較結果正確時,運用比較運算子的運算式將傳回 true,反之將傳回
false。
E-56
範例 E-9:比較運算子的使用
此範例將在 A 等於 7,B 等於 2 的情況下,進行各種比較運算子的計算,
並輸出結果。
[執行結果] 等於運算子: A == B 為 false
大於運算子: A > B 為 true
小於運算子: A < B 為 false
大於等於運算子: A >= B 為 true
小於等於運算子: A <= B 為 false
不等於運算子: A != B 為 true
[程式內容] 檔名:Comparison.java 001 public class Comparison
002 {
003 public static void main(String ary[])
004 {
005 int A = 7 , B = 2; //設定 A、B 變數值
006
007 System.out.println("等於運算子: A == B 為 " + (A == B));
008 System.out.println("大於運算子: A > B 為 " + (A > B));
009 System.out.println("小於運算子: A < B 為 " + (A < B));
010 System.out.println("大於等於運算子: A >= B 為 " + (A >= B));
011 System.out.println("小於等於運算子: A <= B 為 " + (A <= B));
012 System.out.println("不等於運算子: A != B 為 " + (A != B));
013 }
014 }
程式進入點
E-57
Java
基本語法 E
E-4-4 邏輯運算子
Java 的邏輯運算子可分為一般邏輯運算子及快捷邏輯運算子。
一般邏輯運算子
邏輯運算子用於執行布林值的邏輯運算,下表為 Java 所提供的一般邏
輯運算子:
運算子符號 名 稱 使用語法範例 說明 & 且 A & B 當 A、B 均為真時,結果為真 | 或 A | B 當 A、B 其中之一為真時為真 ! 反 ! A 當 A 為真時為假
下表稱為真值表,T(true)代表『真』,F(false)代表『假』,將整理出
當 A、B 在各種情形下,各一般邏輯運算子的運算結果:
A B A & B A | B ! A T T T T F F T F T T F F F F T T F F T F
範例 E-10:邏輯運算子的使用
本範例輸出 A 與 B 在各種情況下,運用各邏輯運算子進行運算後所產
生的真值表。
[執行結果]
輸出的執行結果與前面提到的真值表相同。
A B A&B A||B !A true true true true false false true false true true false false false false true true false false true false
E-58
[程式內容] 檔名:Logical.java 001 public class Logical
002 {
003 public static void main(String args[])
004 {
005 boolean A , B;
006 A = true; //設定 A、B 變數起始值
007 B = true;
008 System.out.println(" A B " + " A&B " + " A||B " + " !A");
009 System.out.println(A+" "+B+" "+(A & B)+" "+(A || B)+
" "+(!A));
010
011 A = false; //設定 A、B 變數值
012 B = true;
013 System.out.println(A+" "+B+" "+(A & B)+" "+(A || B)+
" "+(!A));
014
015 A = false; //設定 A、B 變數值
016 B = false;
017 System.out.println(A+" "+B+" "+(A & B)+" "+(A || B)+
" "+(!A));
018
019 A = true; //設定 A、B 變數值
020 B = false;
021 System.out.println(A+" "+B+" "+(A & B)+" "+(A || B)+
" "+(!A));
022 }
023 }
快捷邏輯運算子
Java 提 供 了 兩 個 特 殊 的 &&(AND) 與 ||(OR) 的 快 捷 邏 輯 運 算 子
(short-circuit operators),其運算結果和&及 |邏輯運算子相同,唯一有別的
地方在於,當&&運算子判斷左邊運算條件不成立後,就不會繼續判斷右邊
的運算條件,直接將條件比較結果視為不成立;反之,||運算子判斷左邊運
算條件成立後,就不會繼續判斷右邊條件,直接將條件比較結果視為成立,
請看下面範例的說明。
程式進入點
E-59
Java
基本語法 E
範例 E-11:邏輯與快捷邏輯運算子的應用
本範例的 Java 輸出 A 與 B 在各種情況下,運用 AND 及 OR 邏輯運算
子及快捷邏輯算子進行運算後,所產生的真值表。
[執行結果] A B A&B A|B A&&B A||B
true true true true true true
false true false true false true
false false false false false false
true false false true false true
若將程式的執行結果利用表格表示,結果如下:
A B A & B A | B A && B A || B true true true true true true false true false true false true false false false false false false true false false true false true
[程式內容] 檔名:COMPAndOr.java 001 class COMPAndOr
002 {
003 public static void main(String args[])
004 {
005 boolean A , B; //宣告 A、B 變數
006
007 A = true; //設定 A、B 變數值
008 B = true;
009 System.out.println("A\tB"+" A&B "+" A|B "+" A&&B "+" A||B");
010 System.out.print(A+" "+B+" "+(A&B)+" ");
011 System.out.println((A|B)+" "+(A&&B)+" "+(A||B));
012
013 A = false; //設定 A、B 變數值
014 B = true;
015 System.out.print(A+" "+B+" "+(A&B)+" ");
016 System.out.println((A|B)+" "+(A&&B)+" "+(A||B));
017
程式進入點
E-60
018 A = false; //設定 A、B 變數值 019 B = false;
020 System.out.print(A+" "+B+" "+(A&B)+" ");
021 System.out.println((A|B)+" "+(A&&B)+" "+(A||B));
022
023 A = true; //設定 A、B 變數值
024 B = false;
025 System.out.print(A+" "+B+" "+(A&B)+" ");
026 System.out.println((A|B)+" "+(A&&B)+" "+(A||B));
027 }
028 }
E-4-5 『=』運算子
在程式中,應該以『指派符號』代替『等號』做為『=』運算子的名稱。
這是因為『=』符號,在程式裡的意義與數學上的意義並不完全相同,但許
多人在觀念上仍以『等號』看待它。在程式中大部份的地方,我們的確也
可以用『等號』的觀念來解釋『=』符號,比如:
式一:A = 1 + 2
很容易地就能看出,A 的值為 3,在這裡用『等號』的觀念解釋上式(式
一)並沒有困難。但是下面的式二也常在程式中出現,比如:
式二:A = A + 1
如果再用『等號』的觀念解釋式二中的『=』符號,就怎麼也說不通了。
其實在程式裡,不應以『等號』的觀念來解釋『=』符號,而應該解釋為『指
派』。在電腦裡,不論式一或者式二,其運算的方式都是先將『=』右邊的
算式計算出來,然後再把這個值『丟』到符號左邊變數所佔的記憶體裡。
所以,應該把『=』視為將值『指派』給變數。
當以『指派』的觀念解釋『=』符號時,式二的意義將可以很容易地解
釋。式二的計算方式,是將 A 中儲存的資料取出來加一後,把這個值放回
A 變數原先儲存的記憶體空間裡。
E-61
Java
基本語法 E
E-4-6 遞增、遞減運算子
在 Java 裡,有++(遞增)運算子與--(遞減)運算子。這兩個運算子,用於
將變數值增加 1 或者減少 1,例如:
i++;
相當於
i = i + 1;
而
i--;
則相當於
i = i - 1;
必須注意的是!當++與--的位置,在變數前與在變數後,計算結果是一
樣的。但是在計算過程中,若您直接輸出運算式的值,當運算子在變數前
時,將先執行運算,然後傳出運算後的值。當運算子在變數後時,將先傳
出變數值,然後再執行計算,在下面的範例中,將說明此觀念。
範例 E-12:遞增運算子的使用
本範例將為您示範遞增運算子的使用,與運算子置於變數前後的差異。
[執行結果] A++ : 0
A : 1
++A : 1
A : 1
[程式內容] 檔名:IncDec.java 001 public class IncDec
E-62
002 { 003 public static void main(String args[])
004 {
005 int A = 0; //設定 A 變數值
006 System.out.println("A++ : " + (A++)); //先傳出值後,再加 1
007 System.out.println(" A : " + A);
008
009 A = 0; //重設 A 的值
010 System.out.println("++A : " + (++A)); //A 由 0 加 1 後,再傳出值
011 System.out.println(" A : " + A);
012 }
013 }
[程式說明]
從下面的執行結果可以看出,將運算子放在 A 變數前或後,計算後的
A 值都相同(第 7、11 列)。但若直接輸出運算式的計算值時,運算子放在 A
變數後,將傳出計算前的值,故第 6 列與第 7 列所輸出的計算結果並不相
同。運算子放在 A 變數前時(第 10 列),所傳出的是計算後的值,所以第 10
列與第 11 列所輸出的計算結果是相同的。
E-4-7 算術指派運算子
算術指派運算子用於結合運算與指派動作,可簡化運算式,以下各種
算術指派運算子的使用範例。
運算子 範例 相當於 += A = A + 3 A += 3 -= A = A – 3 A -= 3 /= A = A / 3 A /= 3 *= A = A * 3 A *= 3 %= A = A % 3 A %= 3
程式進入點
E-63
Java
基本語法 E
範例 E-13:算術指派運算子的使用
[執行結果] A = A + 3 : 5.0
A += 3 : 5.0
A = A - 3 : -1.0
A -= 3 : -1.0
A = A * 3 : 6.0
A *= 3 : 6.0
A = A / 3 : 0.6666666666666666
A /= 3 : 0.6666666666666666
若將程式的執行結果以表格表示,結果如下:
範例 執行結果 範例 執行結果 A = A + 3 5.0 A += 3 5.0 A = A - 3 -1.0 A -= 3 -1.0 A = A * 3 6.0 A *= 3 6.0 A = A / 3 0.6666666666666666 A /= 3 0.6666666666666666
[程式內容] 檔名:ArithAssign.java 001 public class ArithAssign
002 {
003 public static void main(String args[])
004 {
005 double A = 2.0; //設定 A 變數值
006
007 A = A + 3;
008
009 System.out.println("A = A + 3 : " + A);
010
011 A = 2.0; //重設 A 的值
012 A += 3;
013
014 System.out.println("A += 3 : " + A);
015
016 A = 2.0; //重設 A 的值
017 A = A - 3;
018
E-64
019 System.out.println("A = A - 3 : " + A); 020
021 A = 2.0; //重設 A 的值
022 A -= 3;
023
024 System.out.println("A -= 3 : " + A);
025
026 A = 2.0; //重設 A 的值
027 A = A * 3;
028
029 System.out.println("A = A * 3 : " + A);
030
031 A = 2.0; //重設 A 的值
032 A *= 3;
033
034 System.out.println("A *= 3 : " + A);
035
036 A = 2.0; //重設 A 的值
037 A = A / 3;
038
039 System.out.println("A = A / 3 : " + A);
040
041 A = 2.0; //重設 A 的值
042 A /= 3
043 System.out.println("A /= 3 : " + A);
044 }
045 }
E-4-8 各運算子的計算順序
所謂運算子的計算順序觀念,就是當一道運算式中,存在許多運算子
時,處理每一個運算子的順序。若遇到處理順序相同,則以左邊的運算子
優先。這個概念其實就是數學中先乘除後加減的觀念,下表將表達出 Java
中,各類運算子的運算順序。
E-65
Java
基本語法 E
符 號 算術
++(遞增)、 --(遞減)
-(負數)、 +(正數)
*(乘)、 /(除)
% (餘數)
+(加)、 -(減)
比較
==、>、<、>=、<=、!= (優先順序相同,在運算式較左邊的優先)
邏輯 &(且) |(或) &&(且) ||(或) 指派 = (指派)、算術指派
表中各運算子的優先次序為由上至下,由左至右。在運算式中,以算術
運算子最優先。在算術運算子中,又以最左方的++運算子與--運算子為最
優先。所以,當電腦執行到一列運算式時,將會先執行遞增或遞減運算子,
然後再處理其他的運算子。若有括號時,則優先計算括號內的運算式。接
下來,將以下面的例子,說明運算子的處理順序。
5*2 > 6 & 7+8 < 8
首先,電腦將先完成上式中,算術運算子的運算,計算出 5*2=10 與
7+8=15,如下所示:
10 > 6 & 15 < 8
然後,整理比較運算的部份將得到以下結果:
true & false
最後得到結果為 false,我們再舉一個算術運算子的例子:
A = 5 * ( 2 * 2 ) + 6 / 2
第一步先計算括號內的算式(2*2=4),得到下面的結果。
A = 5 * 4 + 6 / 2
再計算乘除,得到下面的結果。
A = 20 + 3
最後得到 A = 23
優先次序
高
低
高 低優先次序
E-66
E-4-9 型別轉換
自動型別轉換
在 Java 中,當算式執行運算時,必須將運算式中,欲計算的所有資料
之型別,都轉換成同一型別。而 Java 亦提供一個自動執行型別轉換的機制,
能夠在執行運算時,自動轉換運算式內資料的型別,例如:『1 + 2.5』這
個式子,1 將會先轉換為 1.0,然後才與 2.5 相加。
自動型別轉換的規則,均是將資料的型別,從佔記憶體空間小者,轉
換為佔記憶體空間大者。舉例來說,int 型別可以表示 byte 型別所代表的資
料。但是 byte 型別卻無法完整表示出所有 int 型別所能表示的資料。所以,
在下面的運算式,b(型別為 byte)乘以 2(型別為 int 的常數),再指派給 i(型
別為 int)時,b 中的資料將會被轉換成 int 型別,然後才乘以 2。
i = b * 2;
接下來,將運用下面這道運算式,並配合運算子的計算優先順序,講
解自動型別轉換的過程。
R = i / d + f * d – l;
式中變數的資料型別為 i(int)、f(float)、d(double)、l(long)、R(double)。
下圖是運算式計算時,資料型別轉換的過程。
i / d + f * d - l 原資料型別 int double float double long
double double
double
型 別 轉 換
R(double) = double
E-67
Java
基本語法 E
強制型別轉換
前面提到,編譯器在編譯的過程中,將自動執行型別轉換。若有需要
時,我們也可以自行強迫轉換型別,其語法如下:
(欲轉換的型別) 運算式;
或
(欲轉換的型別) 變數;
比如,當 7/2 時,由於 7 與 2 都是整數,相除後的計算結果,也是整數。
所以,7/2 的計算結果等於 3,而不是 3.5。想要解決這個問題,可以將 7
先強制轉型為浮點數,再執行運算。
(float)7 / 2;
上式的計算結果則為 3.5。
資料型別的轉換有兩點必須注意。一是布林值資料型別,因為其值只
有 true 和 false 兩種,因此無法型別轉換為其他數字型態的資料型別,這一
點與許多語言是不一樣的,不少語言中 false 的值相當於 0,true 值相當於
0 以外的值。另一點是不同的資料型別所配置的記憶體空間大小亦不同,
因此儲存空間較大的型別,若是轉換空間較小的型別,可能產生資料流失
的情形,例如:long 型別資料轉換 short 型別資料,或是 double 轉換為 float
都可能發生資料流失的情形。
範例 E-14:型別轉換機制
[執行結果] 123 + 123.0 = 246.0
(float)7/2 : 3.5
E-68
[程式內容] 檔名:Convert.java 001 public class Convert
002 {
003 public static void main(String args[])
004 {
005 System.out.println("123 + 123.0 = " + (123 + 123.0));
006 //型別轉換,結果為浮點數
007 System.out.println("(float)7/2 : " + (float)7/2);
008 //強制型別轉換,結果為浮點數
009 }
010 }
[程式說明]
在本範例的第 5 列,將運用自動型別轉換機制執行『123 + 123.0』的計
算,計算結果為 246.0。可見 123 在計算時,型別將先轉換為 float。但在第
7 列中,則強制將 7 轉換浮點數,再進行除以 2 的運算,計算結果為 3.5。
E-5 流程控制
E-5-1 流程控制的用途與種類
流程控制是程式中,用於控制或選擇某一程式區段執行方式的語法。
流程控制分為兩類,一種是判斷敘述,另一種是迴圈。
判斷敘述是利用條件式,決定要執行哪一個程式區段。
迴圈是利用條件式,控制某程式區段的重複執行。
有了流程控制以後,可以讓原先一列接著一列執行的程式,產生許多
變化,並能重複執行某段程式,或者控制某一段程式是否被執行。
程式進入點
E-69
Java
基本語法 E
補給小站
在這些流程控制的語法中,主要是由條件式與保留字所構成。其中條件
式用於傳回『真』或『假』值,做為程式決定是否執行某段程式的依據。
而保留字將以一定的規則,將條件式與欲控制執行的敘述包含在一起。當
程式執行至此處時,依照條件式傳回的『真』、『假』值,來決定接下來
該如何執行程式。以下敘述將分別說明判斷敘述與迴圈的語法。
保留字是指 Java 所使用的特定單字,例如:整數型別中的 int,就
是一個保留字,保留給 Java 所使用。因此,您不可使用保留字做為變數
的名稱。
E-5-2 判斷結構語法
判斷結構最基本類型的語法如下所示:
if (條件式)
程式敘述;
若程式敘述不止一列時,則需用『{…}』,標示這些程式敘述。
if (條件式){
程式敘述
……
}
if 後的條件式,經過運算將傳回 true 或 false。傳回 true 時,則執行程
式敘述。若為 false,則跳過程式敘述。因此,判斷結構語法就是靠條件式
傳回的布林值,做為程式敘述是否被執行的依據。除了 if 敘述外,還有一
種 switch 敘述,說明於 E-5-6 節。
E-70
E-5-3 迴圈控制語法
迴圈控制語法如下所示:
while (條件式){
程式敘述
……
}
若程式敘述只有一列時,可省略『{}與『』』符號。當 while 後的條件
式回傳值為 true 時,則執行程式區段,直到條件式回傳值為 false 才跳出迴
圈。因此,當迴圈被執行時,一定要有改變條件式中,某變數的敘述,否
則條件式的計算結果將永遠不會為 false,也就跳不出這個迴圈的控制。另
一種常見的迴圈控制為 for 敘述(E-5-7 節)。
E-5-4 main()方法的執行參數
執行參數的傳入
由於執行這一節範例時,需要傳遞一些資料給程式,以便進行測試。
本附錄將使用傳遞參數給 main()方法,進行資料的傳遞。以下是 main()方
法的定義語法:
public static void main(String args[]){ 程式敘述;
……
}
在 main()方法中,將定義 args 字串陣列為傳入參數。當在 Dos 模式執
行 Java 程式時,若在檔案名稱後面加上傳入參數,則在 main()方法中,可
以透過 args 字串陣列,取得從指令列傳入的資料。下面的指令,將在執行
E-71
Java
基本語法 E
Input1 程式時,傳入 45。
java Input1 45
上述指令由於僅傳入 1 個資料,該資料將儲存於 args 字串陣列的第 1
個元素。因此,如果在 Input1 程式執行下列敘述時,將輸出 45。
System.out.println(args[0]);
若有三個傳入參數,則分別用 args[0]、args[1]、args[2]引用,依此類推。
範例 E-15:傳資料給 main()方法
[執行結果]
當執行此程式,在指令列中輸入『java Input1 45』後,執行結果如下:
輸入資料為 45
[程式內容] 檔名:Input1.java 001 public class Input1
002 {
003 public static void main(String args[])
004 {
005 System.out.println("輸入資料為" + args[0]);
006 }
007 }
範例 E-16:傳一個以上的資料給 main()方法
[執行結果]
當執行此程式,在 Dos 模式的指令列中,輸入『java Input2 15 20 30』
後,執行結果如下:
輸入的第一個資料為 15
輸入的第二個資料為 20
輸入的第三個資料為 30
E-72
[程式內容] 檔名:Input2.java 001 public class Input2
002 {
003 public static void main(String args[])
004 {
005 System.out.println("輸入的第一個資料為" + args[0]);
006 System.out.println("輸入的第二個資料為" + args[1]);
007 System.out.println("輸入的第三個資料為" + args[2]);
008 }
009 }
資料型別的轉換
在 main()方法中,從 args[]字串陣列取得的資料,其型態為字串。若欲
進行資料轉換時,必須運用 Java 提供的各類別,語法如下:
型別類別 .parseXXX(String 字串)
將傳回字串轉換後得到的數值,語法各部份的說明如下:
型別類別
型別類別為 Java 中,用於處理某資料型別的類別。
parseXXX 所有處理資料型別的類別中,用於將字串轉換為數值的類別方法,
其名稱均為 parseXXX。
字串
欲轉換為數值的字串。
下表為各型別類別以及用於將字串轉換數值的方法。
類別 方法 Integer(整數) parseInt Float(浮點數) parseFloat Double(倍精度) parseDouble
E-73
Java
基本語法 E
以下敘述將把傳入的第 1 個參數,轉換為整數。
int a = Integer.parseInt(args[0]); //轉換輸入為數值
『true』或『false』字串轉換為 boolean 值時,必須利用 Boolean 類別
的 valueOf()方法,該方法為類別方法,使用語法如下:
Boolean.valueOf(String 字串)
下面是語法各部份的說明。
字串
欲轉換為 boolean 值的字串,若該字串為『 true』,則 valueOf()方法將傳回 true。若不是『 true』,則傳回 false。
範例 E-17:傳入資料的型別轉換
[執行結果]
當執行此程式,在 Dos 模式的指令列中,輸入『java parse 15.2』後,
執行結果如下:
輸入資料為 15.2
轉換成數值後為 15.2
[程式內容] 檔名:parse.java 001 public class parse
002 {
003 public static void main(String args[])
004 {
005 System.out.println("輸入資料為" + args[0]);
006
007 float f = Float.parseFloat(args[0]);
//將傳入資料轉換為浮點數
008
009 System.out.println("轉換成數值後為" + f);
010 }
011 }
E-74
E-5-5 if 判斷敘述
if 判斷敘述的種類
if 判斷結構依照功能可以分為以下兩類:
單一條件判斷敘述:利用一條件式控制程式是否執行某程式敘述
或由兩程式敘述中擇一執行,此判斷敘述將利用 if 或 if…else…
建立。
多條件判斷敘述:利用多個條件控制程式所執行的敘述,此判斷
敘述將以 if…else if...else…建立。
單一條件判斷敘述
語法一:(控制單一程式敘述)
if (條件式){
程式敘述
……
}
語法一的意義為,如果(if)條件式為 true,則執行程式敘述,執行流程
圖如下圖所示:
條件式
真
程式敘述
進入判斷式
離開判斷式
假
E-75
Java
基本語法 E
範例 E-18:if 判斷敘述的使用
本範例利用 if 判斷敘述,示範如何以單一條件,控制程式敘述的執行。
[執行結果]
在 Dos 模式的指令列中,鍵入以下指令。
java IfSTMT 150
本範例執行結果如下:
數值介於 100 至 200 之間
[程式內容] 檔名:IfSTMT.java 001 public class IfSTMT
002 {
003 public static void main(String args[])
004 {
005 int a = Integer.parseInt(args[0]); //轉換輸入字串為數值
006
007 if (a >= 100 & a <= 200) //判斷數值是否介於 100 至 200 之間
008 System.out.println("數值介於 100 至 200 之間");
009 //如果上述符合條件則顯示此行
010 }
011 }
語法二:(兩程式敘述擇一執行)
if (條件式) { 程式敘述一
…… } else{ 程式敘述二
…… }
程式進入點
E-76
語法二的意義為,如果(if)條件式為 true,則執行程式敘述一,否則(else)
執行程式敘述二,其執行流程圖如下:
條件式
真
程式敘述一
進入判斷式
離開判斷式
假
程式敘述二
範例 E-19:兩敘述中擇一執行
本範例將利用 if 判斷敘述,示範如何以單一條件式,控制程式於兩程
式敘述中擇一執行。
[執行結果]
在 Dos 模式的指令列中,鍵入以下指令。
java IfElse 45
本範例執行結果如下: 數值小於或等於 100
[程式內容] 檔名:IfElse.java 001 public class IfElse
002 {
003 public static void main(String args[])
004 {
005 int a = Integer.parseInt(args[0]); //轉換輸入為數值
程式進入點
E-77
Java
基本語法 E
006 007 if (a <= 100) //判斷輸入的數值是否小於等於 100
008 {
009 System.out.println("數值小於或等於 100");
010 //如果輸入數值小於或等於 100 則顯示此行
011 }
012 else
013 {
014 System.out.println("數值大於 100");
015 //如果輸入數值大於 100 則顯示此行
016 }
017 }
018 }
範例 E-20:快捷邏輯運算子的使用
本範例將利用 if 判斷敘述,示範利用快捷邏輯運算子判斷變數可否被
整除。
[執行結果] A = 0 is not divided with no remainder
[程式內容] 檔名:ShortLogical.java 001 public class ShortLogical
002 {
003 public static void main(String args[])
004 {
005 int A = 0; //設定 A 變數值
006
007 if(A != 0 && 100 % A == 0)
008 {
009 System.out.println("A is divided with no remainder");
010 //輸出 A 變數值可以整除數值 100 的訊息
011 }
012 else
013 System.out.println("A = " + A +
" is not divided with no remainder");
014 //輸出 A 變數值不可以整除數值 100 的訊息
程式進入點
E-78
015 } 016 }
[程式說明]
若將上一個範例程式的第 6 列之判斷式更改如下:
006 if(A != 0 & 100 % A == 0)
則執行判斷敘述時,由於&運算子判斷左邊條件式為假(false),仍會繼
續判斷右邊的條件式,所以修改此範例第 6 列,使用&運算子後,右邊條
件式執行時,由於 A 為 0 將導致例外的產生,因此,將出現如下的錯誤訊
息。由此,可看出快捷邏輯運算子,在左邊判斷式為假後,便不會再進行
右式的判斷。
Exception in thread "main"
java.lang.ArithmeticException: / by zero
at shotlogical.main(shotlogical.java:6)
多條件判斷敘述
當選擇執行程式的判斷條件不止一個時,就必須利用 if…else if…else
建立流程控制,語法如下:
if (條件式 A){
程式敘述一
……
} else if (條件式 B){
程式敘述二
……
}
else if ……
……
else{
E-79
Java
基本語法 E
程式敘述 N
……
}
該語法的意義為當任一列條件式為 true 時,即執行該列程式後的程式
敘述,若為 false 則跳過該程式敘述。若都不符合所有條件式,則執行 else
後的程式敘述 N,其執行流程圖如下:
條件式A
真
程式敘述一
進入判斷式
離開判斷式
假
程式敘述二
條件式B
條件式C
真
假
程式敘述三
真
假
條件式...
程式敘述N(else敘述)
假
程式敘述...
範例 E-21:多條件判斷敘述的使用
本範例將利用 if 判斷敘述,以多條件式控制程式敘述的執行。
[執行結果]
您可以嘗試輸入不同的值,以觀察此條件判斷敘述的執行狀況。若在
Dos 模式的指令列中,鍵入以下指令。
E-80
java IfElseIfElse 199
則本範例的執行結果如下:
這個數值介於 100 至 200 之間
[程式內容] 檔名:IfElseIfElse.java 001 public class IfElseIfElse
002 {
003 public static void main(String args[])
004 {
005 int a = Integer.parseInt(args[0]); //轉換輸入為數值
006
007 if (a < 100) //判斷輸入的是否為數字
008 {
009 System.out.println("這個數值小於 100");
010 //如果數值小於 100 則顯示此行
011 }
012 else if(a >= 100 & a <= 200)
013 {
014 System.out.println("這個數值介於 100 至 200 之間");
015 //如果數值介於 100 至 200 之間則顯示此行
016 }else
017 System.out.println("這個數值超過 200");
018 //如果數值超過 200 則顯示此行
019 }
020 }
巢狀判斷敘述
常用的 if 判斷式,還有一種可以達成與多條件判斷敘述類似功能的巢
狀判斷敘述。當在判斷式的程式敘述中,又利用一個判斷敘述進行判斷,
此時便有兩層判斷敘述,這就是所謂的巢狀判斷敘述。
if (條件式 A){
if (條件式 B)
程式敘述一;
else
程式進入點
E-81
Java
基本語法 E
程式敘述二;
}
else{ if (條件式 C)
程式敘述三;
else 程式敘述四;
}
上面就是一個兩層的巢狀判斷敘述,將先以條件式 A 執行二分法。符
合條件 A,才再利用條件 B 做判斷,若符合條件 B 的則執行程式敘述一,不
符合的則執行程式敘述二。而一開始便不符合條件 A 者,則利用條件式 C
進行判斷,符合條件式 C 者執行程式敘述三,不符合者執行程式敘述四。下
面是整個巢狀判斷敘述的執行流程。
條件式A
進入判斷式
離開判斷式
假
程式敘述三
條件式C
真假
程式敘述四
真
程式敘述二
條件式B
假真
程式敘述一
E-82
範例 E-22:巢狀判斷敘述的使用
這個範例將利用巢狀判斷敘述,判斷某年是否為閏年。
[執行結果] 西元 2130 年,不是閏年!
[程式內容] 檔名:NestedIf.java 001 public class NestedIf
002 {
003 public static void main(String args[])
004 {
005 int year = 2130; //設定欲判斷之年
006
007 System.out.print("西元" + year + "年");
008
009 if(year % 4 == 0) //可被 4 除盡
010 {
011 if(year % 100 == 0) //可被 4、100 除盡
012 {
013 if(year % 400 == 0) //可被 4、100、400 除盡
014 System.out.println(",是閏年!");
015 else //可被 4、100 除盡,不可被 400 除盡
016 System.out.println(",不是閏年!");
017 }else //可被 4 除盡,不可被 100 除盡
018 System.out.println(",是閏年!");
019 }
020 else //不可被 4 除盡
021 System.out.println(",不是閏年!");
022 }
023 }
[程式說明]
如何判斷某一年是不是閏年呢?首先,要檢查該年可否被 4 除盡。可
被 4 除盡的數字裡,又分為可否被 100 除盡兩類,可被 100 除盡的不是閏
年。可被 4 與 100 同時除盡的裡面,亦分可否被 400 除盡兩類,可被 400
程式進入點
E-83
Java
基本語法 E
除盡的是閏年。從前面的一段敘述裡,我們得知求取閏年的邏輯,在範例
程式內第 9 到 21 列的判斷觀念說明如下:
第一層:
先判斷是否可被 4 除盡,若不可被除盡,則該年不是閏年,並進入第
二層判斷敘述。 009 if(year % 4 == 0) //可被 4 除盡
010 {
011…018 第二層判斷敘述
019 }
020 else //不可被 4 除盡
021 System.out.println(",不是閏年!");
第二層:
當可被 4 除盡,進入第二層判斷敘述,若可以被 100 除盡,則進入第
三層判斷敘述。若不可被除盡,則是閏年。
011 if(year % 100 == 0) //可被 4、100 除盡
012 {
013…016 第三層判斷敘述
017 }else //可被 4 除盡,不可被 100 除盡
018 System.out.println(",是閏年!");
第三層:
如果可被 4 與 100 除盡,則進入第三層判斷敘述後,若可被 400 除盡,
則是閏年。若不可被除盡,則不是閏年。
013 if(year % 400 == 0) //可被 4、100、400 除盡
014 System.out.println(",是閏年!");
015 else //可被 4、100 除盡,不可被 400 除盡
016 System.out.println(",不是閏年!");
E-84
基本上,這個範例程式中巢狀判斷式的觀念,只是重覆使用 if…else,
以二分法的方式找出符合條件的答案。當然如果有需要,您也可以在巢狀
判斷式裡使用 else if 敘述。不過,初學巢狀判斷式的時候,必須要小心,
不要讓您的巢狀判斷式產生交錯的情形。下面提出一個簡單的方塊法,提
供各位用於檢查巢狀判斷式是否產生交錯的情形。請將各層判斷式的區塊
用方塊框起來,如下圖。
009 if(year % 4 == 0) //可被 4 除盡
010 {
011 if(year % 100 == 0) //可被 4、100 除盡
012 {
013 if(year % 400 == 0) //可被 4、100、400 除盡
014 System.out.println(",是閏年!");
015 else //可被 4、100 除盡,不可被 400 除盡
016 System.out.println(",不是閏年!");
017 }else //可被 4 除盡,不可被 100 除盡
018 System.out.println(",是閏年!");
019 }
020 else //不可被 4 除盡
021 System.out.println(",不是閏年!");
如果各方塊沒有產生類似如下所示的方塊交錯情形,則您的巢狀判斷
式在語法上是正確無誤的。
E-5-6 switch 判斷敘述
switch 判斷敘述用於針對某運算式的不同值,進行條件判斷,然後從
多個程式敘述中,選擇執行其中某一程式敘述,語法如下:
E-85
Java
基本語法 E
switch (運算式或變數){
case 條件值一 :
程式敘述一;
break; case 條件值二 :
程式敘述二;
……
break;
default: 程式敘述 N;
break;
}
當執行 switch 敘述時,將先計算 switch 後的運算式,再以計算所得的
值比對各 case 敘述後的值,以決定執行哪一個 case 內的程式敘述,若沒有
符合的條件值,最後將執行 default 內的程式敘述 N,執行流程如下圖所示。
假
進入判斷式
離開判斷式
計算switch後 的條件式值
條件值一 程式區段一真
條件值二 程式區段二真
default 程式區段N
假
......
假
E-86
範例 E-23:switch 判斷敘述的語法
本範例將示範如何利用 switch 判斷敘述,以一個變數控制欲執行的程
式敘述。
[執行結果]
您可以嘗試輸入不同的值,以觀察此條件判斷敘述的執行狀況。若在
Dos 模式的指令列中,鍵入以下指令。
\AppE\SwitchCase>java SwitchCase 1
本範例的執行結果,將如下所示。
1 號車站票價 12 元
[程式內容] 檔名:SwitchCase.java 001 public class SwitchCase
002 {
003 public static void main(String args[])
004 {
005 int a = Integer.parseInt(args[0]);
006
007 switch (a)
008 {
009 case 1: //判斷輸入的是否為 1
010 System.out.println("1 號車站票價 12 元");
011 break;
012 case 2: //判斷輸入的是否為 2
013 System.out.println("2 號車站票價 24 元");
014 break;
015 default:
016 System.out.println("抱歉!沒有這一站!");
017 //如果不是 1 或 2 號車站則執行此程式區段
018 break;
019 }
020 }
021 }
程式進入點
E-87
Java
基本語法 E
範例 E-24:switch 判斷敘述的應用
本範例將示範如何利用 switch 判斷敘述,以一個變數的值控制程式的
執行。
[執行結果] 您是男性!
[程式內容] 檔名:SwitchCase2.java 001 public class SwitchCase2
002 {
003 public static void main(String args[])
004 {
005 char sex = 'm';
006
007 switch (sex)
008 {
009 case 'M': //判斷輸入的字元是否為 M
010 case 'm': //判斷輸入的字元是否為 m
011 System.out.println("您是男性!");
012 break;
013 case 'F': //判斷輸入的字元是否為 F
014 case 'f': //判斷輸入的字元是否為 f
015 System.out.println("您是女性!");
016 break;
017 default:
018 System.out.println("無法判斷您的性別耶!");
019 //超過設定範圍則執行此程式區段
020 break;
021 }
022 }
023 }
程式進入點
E-88
E-5-7 for 迴圈
for 迴圈的基本語法
迴圈語法如下:
for(起始運算式; 測試條件式 ; 遞增運算式){
程式敘述;
……
}
語法中各部份的說明如下:
起始運算式
用於設定計次變數的起始值,起始運算式只在進入迴圈時執行。
測試條件式
計次變數的限制條件式,若為『真』,則進入迴圈執行程式區段,
若為『假』則跳出迴圈。
遞增運算式
每次執行完程式區段後,利用此運算式更改計次變數的值。
下面是一個將執行三次 println()敘述,進行字串輸出的 for 迴圈。
for( i = 1; i <= 3; i = i + 1){
System.out.println("迴圈 3 次執行的第" + i + "次");
}
範例 E-25:for 迴圈的使用
[執行結果]
迴圈 3 次執行的第 1 次
迴圈 3 次執行的第 2 次
迴圈 3 次執行的第 3 次
E-89
Java
基本語法 E
[程式內容] 檔名:ForEx.java 001 public class ForEx
002 {
003 public static void main(String args[])
004 {
005 int i = 0; //宣告變數並設定起始值
006
007 for( i = 1; i <= 3; i = i + 1)
008 {
009 System.out.println("迴圈 3 次執行的第" + i + "次");
010 }
011 }
012 }
[程式說明]
在第 7∼10 列的迴圈內,遞增運算式(i=i+1)亦可運用 i++代替,執行流
程如下圖所示。
i <= 3
真
System.out.println("迴圈3次執行的第" + i +"次");
進入迴圈
離開迴圈
假
i = 1
i = i + 1(i++)
程式進入點
E-90
在上述迴圈的執行過程中,我們將以表格表示迴圈執行過程中,計次
變數值的變化。
執行次數 進入時的 i 值 輸出 執行後的 i
值 第一次 1 迴圈 3 次執行的第 1 次 2 第二次 2 迴圈 3 次執行的第 2 次 3 第三次 3 迴圈 3 次執行的第 3 次 4 第四次 4
由表中,可以看出進入迴圈時,i 值為 1,執行 out.println 這一列敘述,
在網頁中列印出”迴圈 3 次執行的第 1 次”字串。然後,i 值將由 1 更改成為 2。
重覆執行至第三次後,i 的值將被更改為 4,第四次進入迴圈時,由於計次
變數大於 i 值的上限,因而無法進入,將結束迴圈的執行。
範例 E-26:運用 for 迴圈進行數字加總
這個範例將利用 for 迴圈執行 1 至 100 間的數字總和計算。
[執行結果] The sum is 5050
[程式內容] 檔名:Sum.java 001 public class Sum
002 {
003 public static void main(String args[])
004 {
005 int i, sum = 0; //宣告變數並設定起始值,sum 為計算總和用
006
007 // i 用於計次與做為加到 sum 裡的 1 到 100 數字
008 for (i = 1 ; i <= 100 ; i++)
009 sum += i; //每執行一次就把 sum 的值加上 i
010
011 System.out.println("The sum is " + sum + "\n");
//輸出結果
程式進入點
E-91
Java
基本語法 E
012 } 013 }
[程式說明]
以下將運用表格表示出迴圈前四次的執行情形。
執行次數 進入迴圈時 條件式值 sum + i 離開迴圈時 i 值 sum 值 (i <= 100) sum 值 i 值
第一次 1 0 真 0 + 1 1 2 第二次 2 1 真 1 + 2 3 3 第三次 3 3 真 3 + 3 6 4 第四次 4 6 真 6 + 4 10 5 ……
由上面的表格,可以看出程式計算的邏輯,是以 sum 做為加總用, i
一方面供迴圈計次用,另一方面則做為 1 到 100 的數字,然後重覆執行 sum
= sum + i 這列敘述,完成加總計算。
範例 E-27:運用 for 迴圈進行奇數加總
這個範例將利用 for 迴圈執行 1 至 99 奇數的數字總和計算。
[執行結果] The sum is 2500
[程式內容] 檔名:Sum2.java 001 public class Sum2
002 {
003 public static void main(String args[])
004 {
005 int i, sum = 0; //起始值設定
006
007 for (i = 1 ; i <= 99 ; i = i+2)
008 sum += i; //執行累加動作
009
程式進入點
E-92
010 System.out.println("The sum is " + sum); //輸出計算結果 011 }
012 }
範例 E-28:等比級數第 N 項的計算
[執行結果]
若在 Dos 模式的指令列中,鍵入以下指令。
java GEOPro 2 2 2
本範例的執行結果,將如下所示。
等比級數第 2 項值是 4.0
[程式內容] 檔名:GEOPro.java 001 public class GEOPro 002 { 003 public static void main(String args[]) 004 { 005 double a1,r,Rn = 1; //宣告變數,a1 為首項,r 為比,Rn 為 r 的 N 次方 006 int n; // n 代表第 N 項
007 008 a1 = Integer.parseInt(args[0]); 009 r = Integer.parseInt(args[1]); 010 n = Integer.parseInt(args[2]); 011 012 for (int i = 1 ; i < n ; i++) 013 { 014 Rn = Rn * r; 015 } 016 System.out.println("等比級數第" + n + "項值是 " + a1 * Rn); 017 //輸出計算而得的第 N 項值
018 } 019 }
[程式說明]
執行結果所計算的等比級數,若輸出首項為 2,比為 2,則第二項的值
將為 4。
程式進入點
E-93
Java
基本語法 E
在程式的第 8 列至第 10 列,示範了字串陣列 args[]一次讀入不止一個
參數資料的作法,一次讀入 a1、r、n 三個參數值,並將字串轉換為整數。
第 12 列,則示範以即時宣告變數的方式,宣告 i 變數,這在程式撰寫
上是蠻方便的,我們可以在用到變數之前再宣告變數,而不需要回到程式
的最前面宣告變數。
GEOPro.java 程式範例的觀念與前一個 sum 範例的觀念是一樣的,只是
由累加變成了累乘。而 i 只單純地用於迴圈的計次,只是 i 的上限是由使用
者輸入。Rn 則是將等比級數的比累乘 N 次的結果。而第 N 項則在第 16 列
中,利用 a1*Rn 算出。
巢狀 for 迴圈
當一個 for 迴圈中,還有另一個 for 迴圈時,就形成了巢狀 for 迴圈。
for( i = 0; i < 10 ; i++ ){
for( j = 0; j < 10; j++){ 程式敘述
……
}
}
第二層 for 迴圈中,程式敘述所執行的次數,為第一層迴圈執行次數乘
以第二層迴圈的執行次數。以上面的程式片段為例,當第一層迴圈執行一
次,第二層便執行 10 次,所以,第二層迴圈總共執行了 10 * 10 = 100 次。
E-94
範例 E-29:九九乘法表的輸出
本範例將利用巢狀 for 迴圈執行九九乘法表的輸出。
[執行結果] 1x1=1 1x2=2 1x3=3 1x4=4 1x5=5 1x6=6 1x7=7 1x8=8 1x9=9
2x1=2 2x2=4 2x3=6 2x4=8 2x5=10 2x6=12 2x7=14 2x8=16 2x9=18
3x1=3 3x2=6 3x3=9 3x4=12 3x5=15 3x6=18 3x7=21 3x8=24 3x9=27
4x1=4 4x2=8 4x3=12 4x4=16 4x5=20 4x6=24 4x7=28 4x8=32 4x9=36
5x1=5 5x2=10 5x3=15 5x4=20 5x5=25 5x6=30 5x7=35 5x8=40 5x9=45
6x1=6 6x2=12 6x3=18 6x4=24 6x5=30 6x6=36 6x7=42 6x8=48 6x9=54
7x1=7 7x2=14 7x3=21 7x4=28 7x5=35 7x6=42 7x7=49 7x8=56 7x9=63
8x1=8 8x2=16 8x3=24 8x4=32 8x5=40 8x6=48 8x7=56 8x8=64 8x9=72
9x1=9 9x2=18 9x3=27 9x4=36 9x5=45 9x6=54 9x7=63 9x8=72 9x9=81
[程式內容] 檔名:MultiplicationTable.java 001 public class MultiplicationTable
002 {
003 public static void main(String args[])
004 {
005 int i,j;
006
007 for (i = 1 ; i <= 9 ; i++) //i 為乘數
008 {
009 for (j = 1 ; j <= 9 ; j++) //j 為被乘數
010 {
011 System.out.print(i + "x" + j + "=" + i * j + " ");
012 //輸出乘數與被乘數及乘積
013 }
014 System.out.println(" ");
015 }
016 }
017 }
[程式說明]
整個程式的核心,在於第 7 到 15 列的巢狀 for 迴圈,其中外層迴圈以
i 為計次變數,控制九九乘法表的被乘數。內層以 j 為計次變數,控制九九
程式進入點
E-95
Java
基本語法 E
乘法表的乘數,並列印乘法表。同樣地,以表格說明雙層迴圈的執行情形,
我們將該表分成兩個部份,分別說明第一層迴圈與第二層迴圈的執行情況。
進入迴圈的狀態與執行動作:此部份描述進入迴圈的次數、計次變
數值。
離開迴圈的狀態:此部份描述離開迴圈時,計次變數被更改的值。
進入迴圈的狀態與執行動作 離開迴圈的狀態 第一層 第二層 第二層 第一層
執行次數 i 值 執行次數 j 值 j * i j 值 i 值 第一次 1 1x1=1 2 第二次 2 2x1=2 3 第三次 3 3x1=3 4 第四次 4 4x1=4 5 第五次 5 5x1=5 6 第六次 6 6x1=6 7 第七次 7 7x1=7 8 第八次 8 8x1=8 9 第九次 9 9x1=9 10
1
第一次
1
第十次 10 2 第十一次 1 1x2=2 2
第二次
2 …… … … … 2
進入第一層迴圈後,i 值為 1。然後,進入第二層迴圈,第二層迴圈執
行 9 次後,j 值被更改為 10,超過迴圈的執行次數上限,因此跳過迴圈。
上述過程將完成 1x1 到 9x1 之計算結果的輸出。
跳離第二層迴圈後,便利用 println 敘述斷行(第 14 列),完成第一層迴
圈的第一次執行,i 值將被更改為 2,然後開始第一層迴圈的第二次執行。
E-96
範例 E-30:等比級數前 N 項和的計算
[執行結果]
若在 Dos 模式的指令列中,鍵入以下指令。
java GEOProSum 2 2 2
本範例執行結果,如下所示: 第 1 項等比級數為 2.0
第 2 項等比級數為 4.0
The sum is 6.0
[程式內容] 檔名:GEOProSum.java 001 public class GEOProSum
002 {
003 public static void main(String args[])
004 {
005 double a1,r,Rn,sum=0;
006 //定義屬性,a1 為首項,r 為比,Rn 為 r 的 N 次方
007 int n; // n 代表第 N 項
008
009 a1 = Integer.parseInt(args[0]);
010 r = Integer.parseInt(args[1]);
011 n = Integer.parseInt(args[2]);
012
013 for(int i = 1 ; i <= n ; i++)
014 {
015 Rn = 1;
016 for(int j=1; j<I ; j++)
017 {
018 Rn = Rn * r;
019 }
020 System.out.println("第" + i + "項等比級數為" + a1*Rn);
021 //輸出第 N 項值
022 sum += a1*Rn;
023 }
024 System.out.println("等比級數和為" + sum); //輸出總和
025 }
026 }
程式進入點
E-97
Java
基本語法 E
[程式說明]
此程式範例修改自範例 E-28,第 13 列至第 23 列是計算的核心。各迴
圈之計算目的如下:
第一層迴圈:用於計算出第 N 項值,並累加到 sum 裡,以計算級
數項的總和。
第二層迴圈:計算 r 的 N-1 次方,以提供第一層迴圈計算第 N 項
之用。
由上面的敘述,可以知道當第一層迴圈執行第 N 次,欲計算第 N 項時,
第二層迴圈就要執行 N-1 次,以計算 r 的 N-1 次方,所以第二層迴圈的執
行次數,將依第一層迴圈執行的次數,也就是 i 的值而定,因此第二層迴
圈的測試條件式為被設為 j<i。下面以執行結果的輸入資料為例(a1=2、r=2、
n=2),將迴圈執行的過程表示如下表:
進入迴圈 迴圈內的計算過程 離開迴圈 第一層 第二層 第二層 第一層 第一層 第二層 執行次數 i 值 i <= 2 執行次數 j 值 j < i Rn a1*Rn sum j 值 i 值
第一次 1 真 第一次 1 1<1, 假
2*1 = 2
2 1 1
第一次 1 1<2, 真
2 2*2 = 4
6 1 2 第二次 2 真
第二次 2 2<2, 假
2 2
第三次 3 假 3
執行第一次時,第一層迴圈需計算 a1 的值,由於級數第一項的 r 為 0
次方,所以第二層迴圈不需要計算。上表的第一列,第二層迴圈並沒有計
算動作,而第一層迴圈計算出第一項為 2,並將 sum 由 0 加到 2。當第一層
E-98
計算第二次時,需要計算級數第二項,所以第二層迴圈將完整地執行一次,
算出了 r。然後,第一層迴圈計算出級數第二項為 4,並將 sum 由 2 加到 6。
當進入第二層迴圈前,必須將 Rn 重新設定 1,否則計算結果將會造成
錯誤,您可以說出這是為什麼嗎?
從以下執行結果可看出程式先計算出第一、二項值後,最後再算出的
總和。您可以試著在第一層迴圈內,利用 println()方法觀察 sum 值的變化。
E-5-8 while 迴圈
救命!無窮迴圈
使用 while 迴圈時,非常容易遇到程式執行至迴圈後,便無法跳出,因
而造成無窮迴圈的情形。當不幸遇到這種情形時,您只要同時按下鍵盤上
的 + 鍵,就可以強制中斷程式的執行。
while 迴圈語法
while 迴圈的語法如下:
while(條件式){
程式敘述;
……
}
在進入此迴圈時,將會先檢查條件式的值是否為 true,『真』時則進入
迴圈,false 時則跳過此迴圈。進入迴圈以後,每執行迴圈一次,便檢查條
件式值是否為 false。為 false 時,則跳出,true 則繼續執行。因此,在迴圈
內程式敘述的執行過程中,勢必要能夠造成條件式值的變動,否則條件式
的回傳值永遠為 true,將形成無窮迴圈,執行流程如下圖所示。
E-99
Java
基本語法 E
條件式
真
程式敘述
進入迴圈
離開迴圈
假
範例 E-31:應用 while 迴圈計算數字總和
利用 while 迴圈,執行 1 至 99 間奇數的數字總和計算。
[執行結果] The sum is 2500 .
[程式內容] 檔名:WhileSum.java 001 public class WhileSum
002 {
003 public static void main(String args[])
004 {
005 int i = 1, sum = 0; //設定屬性
006
007 while (i <= 99)
008 {
009 sum += i; //執行累加動作
010 i += 2; //增加 i 值
011 }
012 System.out.println("The sum is " + sum + " .");
//輸出結果
013 }
014 }
程式進入點
E-100
[程式說明]
將這個程式範例的 while 迴圈,與範例 E-26 中的 for 迴圈做一下比較。
005 int i = 1, sum = 0;
006
007 while (i <= 99)
008 {
009 sum += i;
010 i += 2;
011 }
005 int i, sum = 0;
006
007 for(i=1;i<=99 ;i=i+2)
008 sum += i;
您會發現兩種迴圈控制方式,似乎只是換了個方式寫,其實許多工作
兩種迴圈都可以完成。只不過 for 迴圈控制執行次數的方式比較單純,適合
執行次數已知,且計次變數的變動亦很規律之情況。而下一個範例所執行
的動作,則是 for 迴圈所無法執行的,因為迴圈的執行次數並不確定。
範例 E-32:運用 while 迴圈求取最大公因數
此範例將利用 while 迴圈,運用輾轉相除法求取兩數的最大公因數。
[執行結果] 20 and 30
The GCD is 10
[程式內容] 檔名:WhileGCD.java 001 public class WhileGCD
002 {
003 public static void main(String args[])
004 {
005 int a = 20 , b = 30 , temp = 0;
//請將 a、b 均設為大於 0 的數
006
007 System.out.println(a + " and " + b);
008
009 while (b != 0)
程式進入點
起始值
終止值條件
計次變數增加
E-101
Java
基本語法 E
010 { 011 temp = a % b ; //求 a,b 相除後的餘數
012 a = b; //將除數(b)換成被除數(a)
013 b = temp; //將前面除得的餘數,設定除數(b)
014 }
015 System.out.println("The GCD is " + a); //最大公因數
016 }
017 }
[程式說明]
以輾轉相除法求取最大公因數,輾轉相除法的觀念如下:
STEP1:欲求最大公因數時,先將兩數相除得一餘數。
STEP2:若餘數為 0,則 STEP1 相除之兩數的除數為兩數之最大公因數。
STEP3:若餘數不為 0,則將 STEP1 相除所得之除數,做為被除數,餘
數做為除數,回到 STEP1。
從以上對輾轉相除法的敘述,可以知道中斷迴圈的測試條件為餘數等
於零時,由於第 11 列中,將 a、b 兩數求得的餘數設定給 temp 變數,所以
在第 13 列,再將 temp 設定給 b,因此繼續迴圈的測試條件式為『b != 0』,
範例程式中 while 迴圈的執行流程如下:
a/b的餘數不等於0
真
temp = a % b; //求 a, b 相除後的餘數 a = b; //將除數(b)換成被除數(a) b = temp; //將前面除得的餘數,設成除數(b)
進入迴圈
離開迴圈
假
E-102
以輾轉相除法的應用,來說明 for 迴圈與 while 迴圈間的差異是最好的
例子。由於我們根本不知道執行輾轉相除法的迴圈,究竟會被執行幾次,
所以必須利用餘數是否為 0,來判斷是否中止迴圈的執行,所以這個時候
使用 while 迴圈是最合適的。在這種情形下,將無法使用 for 迴圈完成這類
運算。
do…while 迴圈
do…while 迴圈的語法如下:
do{ 程式敘述;
…… }while(條件式);
do…while 迴圈的執行過程為先執行程式敘述,然後判斷條件式是否為
『真』,為真則繼續執行,直到條件式值為『假』時跳出。所以,與 while
迴圈是不太一樣的,執行流程圖如下:
條件式
假
程式敘述
進入迴圈
離開迴圈
真
由上述的流程圖可以看出,不論條件式的值為何?迴圈內的程式敘述
至少會被執行一次。
別忘了這個分號
E-103
Java
基本語法 E
範例 E-33:do...while 迴圈的執行
本範例故意將 do…while 迴圈的執行判斷式設為 false,以觀察迴圈的
執行次數。從執行結果可發現即使判斷條件的值為 false,但迴圈中的敘述
仍僅會被執行一次。
[執行結果] 迴圈執行 1 次!
[程式內容] 檔名:DoWhile.java 001 public class DoWhile
002 {
003 public static void main(String args[])
004 {
005 int i = 1, N = 1;
006
007 //雖然判斷條件式為假,但下列迴圈內的敘述仍會被執行一次
008 do
009 {
010 System.out.println("迴圈執行 " + i + " 次!"); 011 i = i+1;
012 }while(N == 0);
013 }
014 }
範例 E-33:運用 do...while 迴圈執行數字加總
本範例將使用 do…while 迴圈,計算 1 至某整數的加總計算。
[執行結果]
若在 Dos 模式的指令行中,鍵入以下指令。
java Sum3 100
本範例的執行結果,如下所示。
sum = 5050
程式進入點
E-104
[程式內容] 檔名:Sum3.java 001 public class Sum3
002 {
003 public static void main(String args[])
004 {
005 int i = 0, sum = 0; //定義屬性
006
007 int n = Integer.parseInt(args[0]); //轉換輸入字串為整數
008
009 do{
010 sum += i;
011 i++;
012 }while(i <= n);
013 System.out.println("sum = " + sum);
014 }
015 }
E-5-9 break 與 continue
break 敘述
在 for 迴圈或者 while 迴圈中,如果想在某條件下,強迫中止迴圈的執
行時,可以利用 if 敘述,配合 break 敘述達到目的。
範例 E-34:使用 break 敘述中斷 for 迴圈的執行
[執行結果] 1~99 奇數累加總合為 2500
[程式內容] 檔名:BreakSTMT.java 001 public class BreakSTMT
002 {
003 public static void main(String args[])
004 {
005 int Sum = 0; //定義屬性
程式進入點
程式進入點
E-105
Java
基本語法 E
006 007 for (int i=1; i <= 200 ; i += 2)
008 {
009 if(i == 101)
010 break; //跳出迴圈
011
012 Sum += i; //執行累加動作
013 }
014 System.out.print("1~99 奇數累加總合為 " + Sum); //輸出計算結果
015 }
016 }
[程式說明]
本程式改寫自範例 E-27,同樣是利用 for 迴圈計算 1 到 99 間,奇數的
總和。只不過在此範例中,並未利用測試條件式,控制 for 迴圈的執行次數。
而是在第 9 列利用 if 判斷敘述,判斷計次變數 i 的值是否等於 101,『是』
則中止迴圈的執行。
範例 E-35:在 while 迴圈中使用 break 敘述
本範例將示範利用 break 敘述,強制中斷 while 迴圈的執行。
[執行結果] 1~99 奇數累加總合為 2500
[程式內容] 檔名:WhileBreak.java 001 public class WhileBreak
002 {
003 public static void main(String args[])
004 {
005 int Sum = 0; //設定屬性
006 int i = 1;
007
008 while(i<=200)
009 {
010 if(i == 101)
程式進入點
E-106
011 break; //跳出迴圈 012 Sum += i; //執行累加動作
013 i += 2; //累加 i
014 }
015 System.out.print("1~99 奇數累加總合為 " + Sum); //輸出計算結果
016 }
017 }
continue 敘述
如果想要中止的不是整個迴圈,而只是想在某條件下,中止某次迴圈
的執行。讓該次迴圈的執行中,能跳過 continue 敘述後的程式敘述,直接
進入下一次迴圈的執行。便可利用 if 敘述配合 continue 敘述,在某條件下,
中止某次迴圈的執行。
範例 E-36:continue 敘述的使用
[執行結果] 1~99 奇數累加總合為 2500
[程式內容] 檔名:ContinueSTMT.java 001 public class ContinueSTMT
002 {
003 public static void main(String args[])
004 {
005 int Sum = 0; //定義屬性
006 int i;
007
008 for (i = 1; i <= 99 ; ++i)
009 {
010 if (i % 2 == 0)
011 continue;
012 Sum += i; //執行累加動作
013 }
014 System.out.println("1~99 奇數累加總合為 " + Sum); //輸出計算結果
015 }
016 }
程式進入點
E-107
Java
基本語法 E
[程式說明]
本程式改寫自範例 E-27,同樣是利用 for 迴圈計算 1 到 99 間奇數的總
和。只不過在此範例中,並未設定計次變數的增加值為 2。而是利用 if 判
斷敘述,判斷計次變數 i 的值是否為偶數(第 10 列),『是』則利用 continue
敘述,中止該次迴圈的執行(第 11 列),因而跳過第 12 列的敘述,直接進入
下一次迴圈的執行。
E-108
Thought is the seed of action. -Emerson
思想為行動的種籽。 -愛默生