Your SlideShare is downloading. ×
4.4      多執行緒(Java          多執行緒(Java Thread)      一般單執行緒的程式,一次只能處理一件事情,如果同時有許多工作需要處理,那就得一個個排隊處理,當然當處理的速度跟不上新增工作的速度時,排隊工作就...
Ready      所有的執行緒在要進入 Running 狀態前都必須先在 Ready 狀態中等待,只有被排程演算法      所挑中的執行緒才可以進入 Running 狀態,並取得 CPU 時間執行程式。      Running     ...
Runnable 介面的方式,主要是由於 Java 並不支援多重繼承,所以當物件己無法在繼承 Thread物件時,這時就可以採用 Runnable 介面的方式,同樣可以擁有多執行緒的能力。下面的範例將分別透過兩種不同的方式實作,同樣都能擁有多執...
static Thread currentThread()傳回現在正在執行的 Thread 物件。  String getName()取得 Thread 的名稱。  int getPriority()取得 Thread 的優先權。  boole...
使此 Thread 睡眠 millis 亳秒的時間。   static void sleep(long millis, int nanos)使此 Thread 睡眠 millis 亳秒加上 nanos 微亳秒的時間。   void start(...
SingleThread obj2 =new SingleThread("t物件二",5);                              new           //物件一開始倒數           obj1.run(); ...
圖 4-11 單執行緒倒數計時器範例【範例程式】多重執行緒-倒數計時器   package com.lattebox.thread;   //MultiThread.java 多執行緒倒數計時器範例   public class MultiTh...
public void run(){             //開始到數計時             for(int i=timeOut;i>=0;i--){             for int                  Syst...
物件,並在建構式中傳入實作 Runnable 介面的物件(RunnableThread ),並呼叫 start()函式將Thread 丟到執行緒排程器中,一個新的執行緒便就此產生。【範例程式】多緒行緒倒數計時器-使用 Runnable 介面實作...
e.printStackTrace();                 }            }            System.out.println(objectName+":倒數結束!");        }    }【執行結果...
public class Bank {    private int money;    private String name;    public Bank(String name, int money) {        this.nam...
Synchronized 的語法• Synchronized Method    synchrnoized public void syncMethod() {    …    }• Synchronized Static Method    ...
• Synchronized(SomeObject)         public void syncMethod() {           synchronized(SomeObject) {             …          ...
notifty()notifyAll()              115
4.7   例外處理(Exception      例外處理(Exception Manager)  何謂例外?  何謂例外?例外,是當程式在執行的過程中,發生了非預期的狀況,也可以說是非預期的錯誤,例如網路程式在進行資料傳輸時,網路突然的斷線...
在 Java 中所有的例外都是 Throwable 的子類別,而在 Throwable 類別後主要又可以分為兩大子類別,分別是 Err 類別與 Exception 類別。  Err 類別:  Err 類別主要是針對程式運作時發生錯誤的狀況,例外...
找不到檔案時會發生的例外事件。   NumberFormatException   字串轉換數字格式不符時所會發生的例外事件。   為您的程式加入例外處理   在 Java 的世界中,例外處理的運作方式相當的簡單,當程式在運作時發生自身無法處理...
}        }    }【執行結果】                               圖 4-14 算術例外範例執行結果另一種例外處理方式為將例外事件丟往上一層函式中去處理,此時上一個函式就必須對接收到的例外事件做出處理,或是...
System.out.println(a+"/"+b+"="+c);             }catch              catch(ArithmeticException e){              catch       ...
【範例程式】自訂例外-定義例外類別    //RangeException.java 自定例外類別    package com.lattebox.exception;    public class RangeException extend...
int students[]=new int[10];               new int//建構式public Average(){    //輸入學生成積    students[0]=100;    students[1]=50;...
//捕捉到RangeException例外               System.out.println(e);           }       }   }【執行結果】                      圖 4-16 計算平均成...
Upcoming SlideShare
Loading in...5
×

Java Thread

20,247

Published on

tk

0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
20,247
On Slideshare
0
From Embeds
0
Number of Embeds
7
Actions
Shares
0
Downloads
29
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Transcript of "Java Thread"

  1. 1. 4.4 多執行緒(Java 多執行緒(Java Thread) 一般單執行緒的程式,一次只能處理一件事情,如果同時有許多工作需要處理,那就得一個個排隊處理,當然當處理的速度跟不上新增工作的速度時,排隊工作就愈一直越排越長,在加上可能有部份比較緊急的工作可是禁不起這般長時間的等待。而多執行緒程式主要是利用切割 cpu 執行時間的方式,讓單一 CPU 可以一次處理多項的工作,每個工作都會分配到一小段的CPU 執行時間,時間一到就換下一個工作執行,由於切割的時間非常的小,在快速的切換執行下每個工作看起來就像是在同時進行一般,但必須特別聲明一點,多執行緒對單一 CPU 的電腦而言並不會真的讓執行的速度變快,只是能讓每個工作都能公平的輪流被執行,而不用等待一段很長的時間,下圖為多執行緒的基本運作原理。4.5 多執行緒運作方式 每一個執行緒就如同一個新的應用程式執行在 JavaVM 之中,一個執行緒從產生到結束,中間可能會經過許多的狀態變化,如待命、休息、暫停、等待、死亡,而這過程就稱為 Thread的生命週期,下圖為執行緒於 JavaVM 中的運作狀態圖: 圖 4-10 執行緒生面週期圖 Initial 一個執行緒被創造出來後首先會進入到 Initial 狀態,對於執行緒對初始設定,直到被呼 叫 Start()函數後才會進入到 Ready 狀態。 102
  2. 2. Ready 所有的執行緒在要進入 Running 狀態前都必須先在 Ready 狀態中等待,只有被排程演算法 所挑中的執行緒才可以進入 Running 狀態,並取得 CPU 時間執行程式。 Running 透過一些排程演算法所挑選出來的執行緒,在進入此狀態後便可取得 CPU 的資源並執行程 式。一直到能夠使用的 CPU 時間到了,或是呼叫了 yield()函式,該緒行緒就會回到 Read 的狀態,等待下次排程程式在次選到。 Sleeping 在 Running 中的執行緒一但被呼叫 sleep()函式後,便會進入到 Sleeping 狀態,一但執 行緒進入睡眠狀態,便會釋放 CPU 資源給其他的執行緒使用,一直到定義的睡眠的時間結 束後並不會立即的回複到 Runnig 狀能,而是會回到 Ready 的狀態,等待下次排程選到它 時才會在繼續執行 sleep 前未完成的工作。 Suspended 當執行使用 suspend()函數時,此執行緒便會進入 Suspended 狀態,一直到呼叫 resume() 函數時才會回到 Ready 狀態。 Blocked 當執行緒中有需要使用到一些 IO 裝置的存取時(如開檔案讀檔),此時執行緒就必須等待 這些裝置的回應,此時執行緒便會進入 Bloaded 狀態。 Dead 當執行緒完成,或是呼叫 stop()函數,則此執行緒便進入 Dead 狀態,一但執行緒進入這 個狀態,便無法在回到其他的狀態,只能等待垃圾收集器(Garbage Collection)來將它收 集走。4.6 Thread 類別和 Runnable 介面 在 Java 語言中要設計多執行緒程式的方法有以下兩種,第一種為透過繼承 Thread 物件,另一種方法則是透過實作 Runnable 介面的方式透過 Thread 物件來為我們執行。之所以會有 103
  3. 3. Runnable 介面的方式,主要是由於 Java 並不支援多重繼承,所以當物件己無法在繼承 Thread物件時,這時就可以採用 Runnable 介面的方式,同樣可以擁有多執行緒的能力。下面的範例將分別透過兩種不同的方式實作,同樣都能擁有多執行緒的功能。 繼承 Thread 藉由繼承 Thread 類別,可讓我們的程式具有多執行緒的能力,在加入執行緒前程式碼只能循序式的進行,若程式中有使用到一些 IO 操作(如檔案讀寫、串流的讀寫),將會造成長時間的等待,而無法繼續執行排在 IO 操作後面的程式碼。例如 System.in.read()函式,執行後程式會等待讀取使用者至鍵盤所輸入資料,若此時鍵盤都無輸入任何資料,則程式便會一直在等待的狀態,排在 IO 等待後的程式碼也就無法被執行,這就有點像一條單行道的馬路,只要途中一台車開的比較慢,或是停在路中間,後面所有的車隊便會同時受到影響,可能會行進變慢,也有可能會完全動彈不得。Thread 類別直接繼承自 Object 類別,並位於 java.lang 套件中,因此在程式中可以直接建立 Thread 物件,而不需要 import 任何套件。以下是 Thread 類別比較常用的的建構式與函式: Thread()建立一個 Thread 物件。 Thread(String name)建立一個 Thread 物件,並指定 Thread 名稱。 Thread(Runnable target)使用 Runnable 介面建立一個 Thread 物件。 Thread(Runnable target, String name)使用 Runnable 介面建立一個 Thread 物件,並指定 Thread 名稱。 static int activeCount()傳回現在正在運行的 Thread 數量。 void checkAccess()確認現在的 Thread 是否允許被存取。 104
  4. 4. static Thread currentThread()傳回現在正在執行的 Thread 物件。 String getName()取得 Thread 的名稱。 int getPriority()取得 Thread 的優先權。 boolean isAlive()測試此 Thread 是否還存活著。 boolean isDaemon()測試此 Thread 是否為背景執行緒。 void join()等待直到此 Thread 結束(死亡)。 void join(long millis)等待此 Thread 結束,最多等待 millis 亳秒。 void join(long millis, int nanos)等待此 Thread 結束,最多等待 millis 亳秒、nanos 微亳秒的時間。 void run()啟動(start)Thread 後所呼叫的函式,如果在建構此執行緒時有指定一個 Runnable 介面,則Runnable 介面的 run()函式將會在此函式中被呼叫。 void setDaemon(boolean on)設定此 Thread 為背景執行緒或使用者執行緒。 void setName(String name)設定此 Thread 名稱。 void setPriority(int newPriority)設定此 Thread 優先權。 static void sleep(long millis) 105
  5. 5. 使此 Thread 睡眠 millis 亳秒的時間。 static void sleep(long millis, int nanos)使此 Thread 睡眠 millis 亳秒加上 nanos 微亳秒的時間。 void start()啟動 Thread,JVM 將會呼叫 Thread 中的 run()函式,自此後將會產生另一條新的執行緒。 String toString()以字串型態傳回此執行緒的相關資訊,包含名稱、優先等級、所屬群組等。緒的 static void yield()使此執行緒暫時的中斷執行,並允許其他執行緒先執行。 在以上 Thread 函式中最主要的兩個函式分別是 start()與 run()函式 當我們呼叫 start() ,函式後,JVM 會將此 Thread 物件丟到執行緒排程器中(scheduler),所有的 Thread 都會經由排程器來決定何時可以被執行。當 Thread 拿到執行權時,run 函式將會被呼叫,在 run()函式中會檢查建構此 Thrad 時有無傳入 Runnable 介面,若有則 Runnable 介面中的 run()函式會被呼叫。因此執行緒中所要執行的程式碼必須撰寫在 run()函式中,並藉由呼叫 start()函式來啟動一個執行緒。以下範例為一個簡單的倒數計時器,當該物件的 run 函式被呼叫後,便會開始倒數計時五秒,並將秒數顯示在螢幕上。為突顯多執行緒與單一執行緒的差別,以下的範例將會分別利用單一執行緒與多執行緒兩種方式撰寫。【範例程式】單一執行緒-倒數計時器 package com.lattebox.thread; //SingleThread.java 單一執行緒-倒數計時器範例 public class SingleThread { //倒數時間 int timeOut=0; //物件名稱 String objectName; public static void main(String[] args) { static //建立兩個物件,分別設定倒數十秒結束 SingleThread obj1 =new SingleThread("物件一",5); new 106
  6. 6. SingleThread obj2 =new SingleThread("t物件二",5); new //物件一開始倒數 obj1.run(); //物件二開始倒數 obj2.run(); } //建構式 public SingleThread (String objectName,int setTime){ int //設定timeOut時間 this.timeOut=setTime; this //設定物件名稱 this.objectName=objectName; this } public void run(){ //開始到數計時 for int i=timeOut;i>=0;i--){ for(int System.out.println(objectName+":倒數"+i+"秒"); try { //暫停1000亳秒,等同於一秒 Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(objectName+":倒數結束!"); } }【執行結果】 107
  7. 7. 圖 4-11 單執行緒倒數計時器範例【範例程式】多重執行緒-倒數計時器 package com.lattebox.thread; //MultiThread.java 多執行緒倒數計時器範例 public class MultiThread extends Thread { //倒數時間 int timeOut=0; //物件名稱 String objectName; public static void main(String[] args) { //建立兩個物件,分別設定倒數十秒結束 MultiThread obj1 =new MultiThread("物件一",5); new MultiThread obj2 =new MultiThread("tt物件二",5); new //啟動物件一執行緒 obj1.start(); //啟動物件二執行緒 obj2.start(); } public MultiThread(String objectName,int setTime){ int //設定timeOut時間 this.timeOut=setTime; this //設定物件名稱 this.objectName=objectName; this } //執行緒進入點,覆寫至Thread類別 108
  8. 8. public void run(){ //開始到數計時 for(int i=timeOut;i>=0;i--){ for int System.out.println(objectName+":倒數"+i+"秒"); try { //暫停1000亳秒,等同於一秒 Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(objectName+":倒數結束!"); } }【執行結果】 圖 4-12 多執行緒倒數計時器 Runnable 介面 利用 Runnable 介面撰寫多執行緒的方式與利用繼承 Thread 的方式並無太大的不同,我們拿前面的倒數計時器範例來做修改,首先在宣告類別名稱的後面必須加上 implementsRunnable,以實作 Runnable 介面。在 Runnable 介面中只有定義一個抽像(abstract)函式run() 所以只需實作 run()函式 並在 run()函式中撰寫所要執行的程式碼 最後在建立 Thread , , , 109
  9. 9. 物件,並在建構式中傳入實作 Runnable 介面的物件(RunnableThread ),並呼叫 start()函式將Thread 丟到執行緒排程器中,一個新的執行緒便就此產生。【範例程式】多緒行緒倒數計時器-使用 Runnable 介面實作 package com.lattebox.thread; //RunnableThread.java 多執行緒範例-使用Runnable介面 public class RunnableThread implements Runnable{ //倒數時間 int timeOut=0; //物件名稱 String objectName; public static void main(String[] args) { //建立兩個物件,分別設定倒數十秒結束 RunnableThread obj1 =new RunnableThread new ("物件一",5); RunnableThread obj2 =new RunnableThread new ("tt物件二",5); //建立Thread物件,並傳入Runnable介面 Thread t1=new Thread(obj1); new Thread t2=new Thread(obj2); new //啟動執行緒一 t1.start(); //啟動執行緒二 t2.start(); } //建構式 public RunnableThread(String objectName,int setTime){ int //設定timeOut時間 this.timeOut=setTime; this //設定物件名稱 this.objectName=objectName; this } //執行緒進入點,覆寫至Thread類別 public void run(){ //開始到數計時 for int i=timeOut;i>=0;i--){ for(int System.out.println(objectName+":倒數"+i+"秒"); try { //暫停1000亳秒,等同於一秒 Thread.sleep(1000); } catch (InterruptedException e) { 110
  10. 10. e.printStackTrace(); } } System.out.println(objectName+":倒數結束!"); } }【執行結果】 圖 4-13 多執行緒倒數計時器-使用 Runnable 介面實作 執行緒的同步(Synchronized) 若同時有多個 Thread 想要存取同一個 Object 的資源,此時必須要有同步機制去避免資料的不一致性。而在 Java 中提供了 synchronized 關鍵字可以讓我們來將 Object 上鎖,每一個要進來存取 Object 內 Method 的 Thread 都必須先取得一把 KEY 後才能進來執行。因此可以避免資料因 Thread 多重存取而造成不一致的狀況。 111
  11. 11. public class Bank { private int money; private String name; public Bank(String name, int money) { this.name = name; this.money = money; } // 存款 public synchronized void deposit(int m){ money += m; } // 領款 public synchronized booleanwithdraw(int m) { if (money >= m) { money -= m; return true; // 已領款 } else { return false; // 餘額不足 } }需要注意的是在 Java 中每個 Object 都有其獨 立的 Lock Key。如下圖所示,當Object one 被 lock 後,並不會影影 Object Two 的運作。 112
  12. 12. Synchronized 的語法• Synchronized Method synchrnoized public void syncMethod() { … }• Synchronized Static Method synchrnoized static public void syncMethod() { … }• Synchronized(this) public void syncMethod() { synchronized(this) { … } } 113
  13. 13. • Synchronized(SomeObject) public void syncMethod() { synchronized(SomeObject) { … } } Thread 的協調運作Java 使用 wait、notifty 來處理 Thread 之間的流程控制。當 Thread 之間具有相依性需要交互運作時,可使用 wait 來將某些 Thread 進入等待,接著將需要運作的 Thread 重新喚起(notify)處理,如此可以控制 Thread 的運作順序與交互的運作流程。。wait() 114
  14. 14. notifty()notifyAll() 115
  15. 15. 4.7 例外處理(Exception 例外處理(Exception Manager) 何謂例外? 何謂例外?例外,是當程式在執行的過程中,發生了非預期的狀況,也可以說是非預期的錯誤,例如網路程式在進行資料傳輸時,網路突然的斷線,或是要開啓一個檔案時,該檔案卻不存在,以上的這些情形皆稱為例外。較以往傳統對例外的處理方式,主要是利用 if 語法來判斷該段程式的執行結果是否正確,並對錯誤的情況做出適當的處理。但是使用 if 語法的缺點為程式會變的相當的冗長,一但要處理的例外狀況變多時,對於各種例外狀況的管理與維護將會是一件相當另人頭痛的事。在 Java的語法中對於例外處理提供了另外一種機制,以物件化的方式來表達和種不同的例外狀況,並以 try catch 的架構來簡化例外處理的判斷。例外處理的基本語法: try{ //可能會發生例外狀況的程式片段 }catch(ExceptionTypeOne e1){ //e1 例外處理程式 }catch(ExceptionTypeTwo e2){ //e2 例外處理程式 }finally{ //無論有無發生例外,皆會執行此處 }例外的處理語法與 swtich case 相當的類似,都是以區塊的方式來將不同的例依各別的方式進行處理。而各種不同可能會發生的例外狀況,則皆以物件的方式來表達,我們可以直接利用Java 內定義好的例外物件來做判斷,也可以自行定義適合的例外物件。 116
  16. 16. 在 Java 中所有的例外都是 Throwable 的子類別,而在 Throwable 類別後主要又可以分為兩大子類別,分別是 Err 類別與 Exception 類別。 Err 類別: Err 類別主要是針對程式運作時發生錯誤的狀況,例外記憶體不足、堆疊溢位等..,這 類的錯誤通常很難預期何時會發生,發生往往都會造成系統嚴重的錯誤,相對的也相當不 容易做處理。, Exception 類別: Exception 主要是用來捕捉程式束預期可能會發生的例外狀況,使用者可以利用此類別自 訂所需的例外類別。底下為部份 Java 己為我們訂義的一些例外類別: NullPointException 當物件指向 Null 時所發生的例外事件。 RuntimException 執行時期所會發生的例外事件。 ClassNotFoundException 找不到類別時所會發生的例外事件。 ClassCastException 類別無法進行轉型時所發生的例外事件。 IOException 有關 IO 處理所會發生的例外事件 ArithmeticException 進行算術運算處理時,所會發生的例外事件。 InterrupedException 進行中斷處理時所會發生的例外事件。 FileNotFoundException 117
  17. 17. 找不到檔案時會發生的例外事件。 NumberFormatException 字串轉換數字格式不符時所會發生的例外事件。 為您的程式加入例外處理 在 Java 的世界中,例外處理的運作方式相當的簡單,當程式在運作時發生自身無法處理的狀況時,便會將這個狀況往更上一個層級丟去,這裡指的上一個層級可能父類中所覆寫的函式,或是丟往上一個呼叫函式。有人丟出例外就必須有人撿,所以一但你所使用的 Java 函式有發出例外的可能,Java 就會強制規定你必須對該例外做出回應動作,你可以選擇利用 trycatch 將該例外抓取下來,並進行處理,或是不對例外做處理,而直接把發生的例外丟往呼叫上一層函式。簡單的說 try 區塊是負責接收程式所丟出的例外物件,而 catch 則是比較所接收到的例外物件是否己有訂義處理的方式。所以說一組 try 區塊可以同時搭配多組的 catch 區塊,依照不同的例外狀況做個各的處理動作。 下列範例為算術運算例外事件範例,當我們在進行算術運算時,若發生除以 0 的情況,便會發生此例外事件。在程式中利用 try catch 語法,將進行算術運算的程式片段給包裝起來,一但在此段程式碼中發生算術例外處理時,系統便捉取到例外事件的發生,並找到ArithmeticException 例外時的處理方式。【範例程式】除零例外: package com.lattebox.exception; //Ex1.java ArithmeticException例外範例 public class Ex1 { public //程式進入點 public static void main(String args[]){ try{ try int a=0; int c=100/0; }catch catch(ArithmeticException e){ catch System.out.println("發生除零例外。"); System.out.println(e); 118
  18. 18. } } }【執行結果】 圖 4-14 算術例外範例執行結果另一種例外處理方式為將例外事件丟往上一層函式中去處理,此時上一個函式就必須對接收到的例外事件做出處理,或是在繼續的往上層丟。下例為一個 NumberFormatException 範例,在此範例中,例外發生時並不會在該函式中立即的被處理,而是會被丟往上一層的函式中去進行例外的處理。在函式宣告時必須利用關鍵字 throws 關建字宣告所可以可以拋出的例外名稱,可以同時宣告多組例外物件只需在每個名稱後面加上逗號(,),在函式中則可利用 throw 關鍵字拋出例外物件,所拋出的例外必須是函式上所宣告的例外或是其子類別。【範例程式】除零例外-丟出例外: package com.lattebox.exception; //Ex2.java 自行丟出例外範例 public class Ex2 { // 程式進入點 public static void main(String args[]){ try{ try int a=100; int b=0; int c=0; //建立Ex2物件 Ex2 ex=new Ex2(); new //呼叫相除函式 c=ex.division(a,b); //輸出結果 119
  19. 19. System.out.println(a+"/"+b+"="+c); }catch catch(ArithmeticException e){ catch System.out.println("發生除零例外。"); System.out.println(e); } } //除法函式 public int division(int a , int b) throws ArithmeticException{ int //若除數為零則丟出例外 if(b==0) if throw new ArithmeticException(); //傳回結果 return a/b; } }【執行結果】 圖 4-15 自行丟出除零例外 自行定義所需的例外 到目前為止我們所使用的例外類別都是 Java 為我們所訂義好的,雖然 Java 所提供的例外類別己相當的豐富,但還是有許多比較特別的例外狀態,是 Java 的例外類別中無法提供的,此時就必須量身訂做一個專屬的例外類別,以更符何程式的設計需求。 在先前我們有介紹過,所有的例外類別都是 Throwable 的子類別,因此我們只需要找一個Throwable 底下的子類別來繼承,就可以建立一個獨立的例外例別。如下範例為一個自定例外類別,繼承至 Exception 類別, 120
  20. 20. 【範例程式】自訂例外-定義例外類別 //RangeException.java 自定例外類別 package com.lattebox.exception; public class RangeException extends Exception { //建構式 public RangeException() { //往上呼叫父類別建構式 super(); super } //建構式,包含例外描述文字 public RangeException(String message) { //將描述文字往上傳給父類別建構式。 super(message); super } } 在定義完一個獨立的例外類別後,接著我們要為該例外決定拋出的時機,也就是定義所處理的例外狀況為何,這完全是由程式設計員依程式的需求而定,只要認定有該例外狀況發生,便可以依據此例外類別建立新的例外物件,並利用 throw 關鍵字將例外物件丟出,當然在丟出例外所屬的函式上也必須利用 throws 關鍵字宣告可丟出 RangeException 類別,最後例外類別將會傳回到呼叫該函式的來源,並同時被 try catch 機制所捕捉,做出適當的回應或處理。在本範例中 RangeException 將被定位為處理輸入值範圍錯誤的狀況,例如一個成積輸入函式,應當輸入的數值範圍為 0~100 分,若輸入數直不在此範圍中,則將會拋出 RangeException例外。以下為一個簡單的計算成積平均程式,在陣例中存放著不同人的考試成積,但其中有二個人的輸入值有誤,一個超過了 100 分,一個則為負數,兩者都並不在規定的 0~100 的範圍內,此時 RangeException 例外就會被發出,並顯示錯誤訊息於螢幕上。【範例程式】自訂例外-拋出例外 package com.lattebox.exception; //Average.java 拋出自定例外範例程式 public class Average { 121
  21. 21. int students[]=new int[10]; new int//建構式public Average(){ //輸入學生成積 students[0]=100; students[1]=50; students[2]=-20; students[3]=55; students[4]=70; students[5]=150; students[6]=85; students[7]=90; students[8]=77; students[9]=60;}//計算平均函式,並宣告可拋出RangeException例外public int average() throws RangeException{ int sum=0; int score=0; for int i=0;i<10;i++){ for(int score=students[i]; //若成積小於0大於100則丟出例外 if(score<0 || score>100){ if throw new RangeException("學生"+i+ ":分數為"+score+"並不在0~100範圍內"); } //將成積加總 sum+=score; } //傳回結果 return sum/students.length;}//程式進入點public static void main(String argsp[]){ Average ave = new Average(); //利用try catch捕捉例外 try { //呼叫計算程式函式 ave.average(); } catch (RangeException e) { 122
  22. 22. //捕捉到RangeException例外 System.out.println(e); } } }【執行結果】 圖 4-16 計算平均成積範例執行結果 123

×