分析Java中的事宜處置與異常處置機制。本站提示廣大學習愛好者:(分析Java中的事宜處置與異常處置機制)文章只能為提供參考,不一定能成為您想要的結果。以下是分析Java中的事宜處置與異常處置機制正文
1、事宜處置
其實,由事宜處置這個名字天然就想到MFC中的新聞呼應機制,就我的領會,它們應當算是南桔北枳的情況吧,我疑惑Java中的事宜處置這個"新瓶"應是裝的MFC中的新聞呼應這個"舊酒"。
所謂的"事宜"即如鍵盤按鍵、鼠標點擊等這類由舉措或甚麼招致某個狀況轉變並須要對這個轉變作響應呼應的這類轉變。我們可以將Java中的事宜分為按鈕、鼠標、鍵盤、窗口、其它事宜這幾年夜類。
事宜處置模子
1. 基於繼續的事宜處置模子(JDK1.0)
JDK1.0中,事宜處置是基於繼續的,事宜先發送到組件,然後沿容器條理向上流傳。沒有被組件處置的事宜會主動地持續流傳到組件的容器。——這個與MFC中的原始事宜呼應次序或許多態的呼應機制仿佛分歧,爾後面說的基於署理的事宜處置機制仿佛又與MFC的回調機制分歧。
詳細的處置辦法
挪用action()辦法或handleEvent()辦法來獲得法式運轉時產生的事宜,一切組件產生的事宜都在此辦法中處置。
2、基於署理的事宜處置模子(JDK1。1)
在這個模子中,事宜被直接送往發生這個事宜的組件,
關於每個組件注冊一個或多個稱為監聽者的類,這些類包括事宜處置器,用來吸收和處置這個事宜。
監聽者就是完成了Listener接口的類。事宜是只向注冊的監聽者申報的對象。每一個事宜都有一個對應的監聽者接口。
在Button對象上用鼠標停止點擊時,將發送一個ActionEvent事宜。這個ActionEvent事宜會被應用addActionListener()辦法停止注冊的一切ActionListener的actionPerformed()辦法吸收。
基於署理的事宜處置模子的特色
①事宜不會被不測地處置。在條理模子中,一個事宜能夠流傳到容器,並在非預期的條理被處置。
②有能夠創立並應用適配器(adapter)類對事宜舉措停止分類。
③有益於把任務散布到各個類中。
重點進修這類事宜處置模子
3、事宜
事宜處置的三要素。
(1)事宜源 事宜源是一個事宜的發生者,如按鈕、窗口及文本域等。
(2)事宜類型 Java中一切的事宜都封裝成一個類,這些事宜類被集中在java.awt.event包,一切的事宜類均繼續了AWTEvent類和一個辦法——getSouce()辦法,該辦法前往產生事宜的對象。
(3)事宜監聽器 分歧的類型事宜產生後,由事宜監聽器吸收事宜並挪用響應的事宜處置辦法。一切的事宜監聽器現實上都是一個java.awt.event包中的接口,引入了java.util.EventListener接口。分歧事宜類型的監聽用具有分歧的辦法。
事宜處置步調
① 法式參加java.awt.event包:
Import java.awt.event;
② 給所需的事宜源對象注冊事宜監聽器:
事宜源對象.addXXXListener(XXXListener);
③ 完成響應的辦法。假如某個監聽器接口包括多個辦法,則須要完成一切的辦法
例:b2.addActionListener(this)
4、事宜Adapters(適配器)
完成每一個Listener接口的一切辦法的任務量長短常年夜的,為了便利起見,Java說話供給了Adapters類,用來完成含有多個辦法的類。
你界說的Listener可以繼續Adapter類,並且只需重寫你所須要的辦法。
例如,窗口事宜對應的監聽器為WindowListener,它必需完成多個辦法,包含windowOpened()、windowClosed()、windowClosing()、WindowIconfied()、WindowDeiconfied()、WindowActivated()、WindowDeactivated(),如許加年夜了不用要的編程任務量。
假如繼續了WindowAdapter,就只需完成個中某一個或幾個辦法,不須要完成一切的辦法。前面許多的例子都只完成windowClosing()一個辦法,目標是在封閉窗口時加入體系。
4.1 按鈕事宜的處置
點擊按鈕所產生的事宜為舉措事宜
舉措事宜對應的事宜類是ActionEvent類
舉措事宜對應的事宜監聽器為: ActionListener
監聽器的重要辦法:
actionPerformed(ActionEvent e)產生舉措事宜時被挪用
完成舉措事宜的操作工程:
第一步,注冊舉措事宜監聽器addActionListener(ActionListener)。
第二步,完成ActionListener接口的辦法:actionPerformed(ActionEvent e)
4.2鼠標事宜的處置
觸發鼠標事宜的事宜源平日是一個容器,當鼠標進入、分開容器,或許在容器中單擊鼠標、拖動鼠標等操作時,都產生鼠標事宜
鼠標事宜對應的事宜類是MouseEvent類
MouseEvent類中辦法:
getX()獲得鼠標的X坐標
getY()獲得鼠標的Y坐標
getPoint()獲得鼠標的地位
鼠標事宜對應的事宜監聽器有兩個:MouseListener(或許MouseAdapter)對應鼠標事宜,MouseMotionListener(或許MouseMotionAdapter)對應鼠標挪動事宜。
MouseListener(或許MouseAdapter)的重要辦法
MousePressed(MouseEvent e)鼠標按下時的處置辦法
MouseReleased(MouseEvent e)鼠標釋放時的處置辦法
MouseEntered(MouseEvent e)鼠標進入時的處置辦法
MouseExited(MouseEvent e)鼠標分開時的處置辦法
MouseClicked(MouseEvent e)鼠標點擊時的處置辦法
MouseMotionListener(或許MouseMotionAdapter)的重要辦法
MouseMoved(MouseEvent e)鼠標挪動時的處置辦法
MouseDraged(MouseEvent e)鼠標拖動時的處置辦法
4.3 鍵盤事宜的處置
在具有鍵盤核心的組件中按下或釋放鍵盤等操作時,都產生鍵盤事宜
鍵盤事宜對應的事宜類是KeyEvent類
KeyEvent類重要辦法:
getKeyCode()取得按下或釋放的鍵代碼
getKeyText()取得按下或釋放的鍵的字符串
鍵盤事宜對應的事宜監聽器為:KeyListener或KeyAdapter
重要辦法:
KeyPressed(KeyEvent e)按下鍵盤時的處置辦法
KeyReleased(KeyEvent e)釋放鍵盤時的處置辦法
4.4 窗口事宜的處置
有Window及其擴大類(Frame、Dialog)等能力激起窗口事宜,表現窗口處於激活/有效狀況、圖標/非圖標狀況或翻開/封閉狀況等
窗口事宜對應的類為WindowEvent,監聽器為WindowListener(或WindowAdapter)
重要辦法:
windowOpened(WindowEvent e)翻開窗口的事宜處置
windowClosed(WindowEvent e)封閉窗口的事宜處置
windowClosing(WindowEvent e)正在封閉窗口的事宜處置
WindowActivated(WindowEvent e)激活狀況的事宜處置
WindowDeactivated(WindowEvent e)有效狀況的事宜處置
4.5 其它事宜的處置
4.5.1 復選框、單選鈕事宜處置
事宜類是ItemEvent :
選項事宜對應的事宜監聽器為: ItemListener
辦法:
itemStateChanged (ItemEvent e)產生選項事宜時被挪用
4.5.2 轉動條事宜處置
調劑事宜對應的事宜類是AdjustmentEvent類 :
調劑事宜對應的事宜監聽器為: AdjustmentListener
辦法:
adjustmentValueChanged (AdjustmentEvent e)產生調劑事宜時被挪用
4.5.3 下拉列表的事宜處置
事宜類是ItemEvent :
選項事宜對應的事宜監聽器為: ItemListener
辦法:
itemStateChanged (ItemEvent e)生下拉列表產生了舉措時被挪用
(可見,下拉列表的事宜處置與事宜類型、事宜監聽器及辦法與復選框、單選框的事宜處置的事宜類型、事宜監聽器及辦法一樣)
4.5.4 菜單事宜的處置
菜單事宜普通是當我們點擊某個菜單項時所產生的事宜。
菜單項有兩種:
MenuItem 舉措事宜
CheckboxMenuItem,選項事宜
MenuItem的事宜處置
第一步,給一切的MenuItem菜單項注冊舉措事宜監聽器addActionListener(ActionListener)。
第二步,完成ActionListener接口的辦法:actionPerformed(ActionEvent e)。在該辦法頂用e.getSource()獲得用戶所選的菜單項,並停止響應的處置。
CheckboxMenuItem的事宜處置
第一步,給一切的CheckMenuItem菜單項注冊選項事宜監聽器addItemListener(ItemListener)。
第二步,完成ItemListener接口的辦法:itemStateChanged(ItemEvent e)。在該辦法頂用e.getSource()獲得用戶所選的菜單項,e.getItem()獲得用戶所選的菜單項的標簽,e.getStateChange()獲得能否選中,並停止響應的處置。
2、異常處置
任何好的編程說話和編程人員都不會疏忽對異常的處置,作為比擬熱點的面向對象編程的說話——Java,異常處置機制天然也是其主要特點之一。
普通說明異常,都將其說為:編程中的毛病。然則,現實上這個毛病可長短常頻仍,有多種,如:編譯毛病、運轉毛病(詳細上又分為:體系運轉毛病和邏輯運轉毛病,這個甚麼體系運轉毛病,本身倒很少將其算作是編程中的毛病了,之前。)
在JAVA中,異常是一個類,它繼續自Throwable類。每一個異常類代表了運轉毛病(留意:是運轉毛病)。異常類中包括了該運轉毛病的信息及處置毛病的辦法等外容。
Java的異常處置機制:
每當Java法式運轉進程中產生一個可辨認的運轉毛病時,(即該毛病有一個異常類與之絕對應時),體系都邑發生一個響應的該異常類的對象,(留意:叫做發生一個異常類對象。)即發生一個異常。
一旦一個異常對象發生了,體系中就必定要有響應的機制來處置它,確保不會發生逝世機、逝世輪回或其他對操作體系的傷害,從而包管了全部法式運轉的平安性
異常和異常類:
Error:由Java虛擬機生成並拋出,Java法式不做處置.
Runtime Exception(被0除等體系毛病,數組下標超規模):由體系檢測, 用戶的Java 法式可不做處置,體系將它們交給缺省的異常處置法式(留意:出缺省的異常處置).
Exception(法式中的成績,可預知的): Java編譯器請求Java法式必需捕捉或聲明一切的非運轉時異常
用戶本身發生異常
Exception類
結構函數:
public Exception();
public Exception(String s);可以接收字符串參數傳入的信息,該信息平日是對該異常所對應的毛病的描寫。
Exception類從父親Throwable那邊還繼續了若干辦法,個中經常使用的有:
1)public String toString();
toString()辦法前往描寫以後Exception 類信息的字符串。
2)public void printStackTrace();
printStackTrace()辦法沒有前往值,它的功效是完成一個打印操作,在以後的尺度輸入(普通就是屏幕)上打印輸入以後破例對象的客棧應用軌跡,也即法式前後挪用履行了哪些對象或類的哪些辦法,使得運轉進程中發生了這個破例對象。
體系界說的運轉異常
這些子類有些是體系事前界說好並包括在Java類庫中的,稱為體系界說的運轉異常
用戶自界說的異常
關於某個運用所獨有的運轉毛病,則須要編程人員依據法式的特別邏輯在用戶法式裡本身創立用戶自界說的異常類和異常對象
用戶界說的異常平日采取Exception作為異常類的父類
然則這裡有一個還未弄懂的成績:產生一個毛病,體系怎樣曉得是可辨認的?又是怎樣發生響應異常類對象?異常類對象怎樣就曉得去用響應辦法處理?每一個處置響應異常的異常類對象豈非就只要一個異常處置辦法?————————————本來,由用戶自界說的異常,是經由過程語句throw才拋出異常。
創立用戶自界說異常時,普通須要完成以下的任務:
1)聲明一個新的異常類,使之以Exception類或其他某個曾經存在的體系異常類或用戶異常為父類。
2)為新的異常類界說屬性和辦法,或重載父類的屬性和辦法,使這些屬性和辦法可以或許表現該類所對應的毛病的信息。
異常的拋出
Java法式在運轉時假如激發了一個可以辨認的毛病,就會發生一個與該毛病絕對應的異常類的對象,把這個進程叫做異常的拋出,
現實是響應異常類對象的實例的拋出。
依據異常類的分歧,拋出異常的方法有體系主動拋出和用戶拋出兩種:
1、體系主動拋出
所用的體系界說的運轉毛病異常都是由體系主動地拋出
2、用戶拋出
用戶自界說的異常弗成能依附體系主動拋出,而必需由用戶用Java語句拋出,在Java語句中,throw語句用來明白地拋出一個“異常”
用throw語句拋出的格局
前往類型 辦法名(參數列表) throws 要拋出的異常類名列表{
…
throw 異常類實例;//留意這裡
…
}
留意:
1)普通當法式中知足某個前提時才拋出異常;
常常把throw語句放在if語句的if分支中,
if(I>100)
throw (new MyException());
2)含有throw的語句的辦法,應該在辦法頭界說中增長以下的部門:
throws 要拋出的異常類名列表
如許做重要是為了告訴欲挪用這個辦法的下層辦法,預備接收和處置它在運轉中能夠會拋出的異常
假如辦法中的throw語句不止一個,則應當在辦法頭throws中列出一切能夠的異常
3)Java說話請求一切用throws症結字聲明的類和用throw拋出的對象必需是Throwable類或其子類。假如你試圖拋出一個不是可拋出(Throwable)對象,Java編譯器將會報錯
異常處置:
重要斟酌若何捕獲異常,捕獲異常後法式若何跳轉,和若何寫異常處置語句
1.try…catch…finally 塊
1)try
在try語句的{ }中包括了能夠會拋出一個或多個異常的一段法式代碼
這些代碼現實上指定了它前面的catch塊所能捕獲的異常的規模。
Java法式運轉到try塊中的語句時假如發生了異常,就不再持續履行該try塊中其他的語句,而是直接進入catch塊中尋覓第一個與之婚配的異常類型並停止處置。
2)catch塊
catch語句的參數相似於辦法的界說,包含一個異常類型和一個異常對象。
異常類型必需為Throwable類的子類,它指清楚明了catch語句所處置的異常類型;
異常對象則由Java運轉時體系在try所指定的法式代碼塊中拋出的年夜括號中包括異常對象的處置的辦法代碼。
catch語句可以有多個,分離處置分歧類型的異常。
Java運轉時體系從上到下分離對每一個catch語句處置的異常類型停止檢測,直到找到與之相婚配的catch語句為止。
這裡,類型婚配指catch中的異常類型與生成的異常對象的類型完整分歧或許是異常對象的父類,是以,catch語句的排序次序應當是從特別到普通。(斟酌為何?)
3)finally塊
finally語句可以說是為異常處置事宜供給的一個清算機制,普通用來封閉文件或釋放其他體系資本
在try-catch-finally語句中可以沒有finally部門的語句。
假如沒有finally部門,則當try指定的法式代碼拋出一個異常時,其他的法式代碼就不會被履行;
假如存在finally部門,則豈論try塊中能否產生了異常,能否履行過catch部門的語句,都要履行finally部門的語句。
可見,finally部門的語句為異常處置供給了一個同一的出口。
多異常處置
一個try塊能夠會發生多種分歧的異常,假如願望能采用分歧的辦法來處置這些破例,就須要應用多異常處置機制。
多異常處置是經由過程在一個try塊前面界說若干個catch塊來完成的,每一個catch塊用來吸收和處置一種特定的異常對象
經由過程catch塊的參數來斷定一個異常對象能否應為本catch塊吸收和處置的異常。
被哪一個catch塊獲得,依據異常對象與catch塊的異常參數的婚配情形:當它們知足上面三個前提的任何一個時,以為異常對象和參數婚配:
1)異常對象與參數屬於雷同的破例類。
2)異常對象屬於參數破例類的子類。
3)異常對象完成了參數所界說的接口。
假如try塊發生的異常對象被第一個catch塊所吸收,則法式的流程將直接跳轉到這個catch語句塊中,語句塊履行完後就加入以後辦法,try塊中還沒有履行的語句和其他的catch塊將被疏忽
假如try塊發生的異常對象與第一個catch塊不婚配,體系將主動轉到第二個catch塊停止婚配,假如第二個仍不婚配,就轉向第三個、第四個……直到找到一個可以吸收該異常對象的catch塊,完成流程的跳轉。
假如try塊發生的異常對象被第一個catch塊所吸收,則法式的流程將直接跳轉到這個catch語句塊中,語句塊履行完後就加入以後辦法,try塊中還沒有履行的語句和其他的catch塊將被疏忽
假如try塊發生的異常對象與第一個catch塊不婚配,體系將主動轉到第二個catch塊停止婚配,假如第二個仍不婚配,就轉向第三個、第四個……直到找到一個可以吸收該異常對象的catch塊,完成流程的跳轉。
若try塊中一切語句的履行都沒有激發異常,則一切的catch塊都邑被疏忽而不履行。
留意:
1)catch塊中的語句應依據異常的分歧履行分歧的操作
所以在處置多異常時應留意賣力設計各catch塊的分列次序。普通地處置較詳細和較罕見的異常的catch塊應放在後面,而可以與多種異常相婚配的catch塊應放在較後的地位。
/*測驗考試用戶運轉毛病的異常處置: 成績是如許的,當輸出的用戶工資初值少於800則是毛病的,固然工資的變更假如跨越20%,則也是毛病的 */ import java.awt.*; import java.applet.*; import java.awt.event.*; public class UserExceptionApplet extends Applet implements ActionListener{ Label prompt1=new Label("請輸出雇員姓名和工資初值:"); Label prompt2=new Label("請輸出欲修正的工資"); TextField name,isal,nsal; String msg; Employee Emp; Button okBtn=new Button("OK"); Button cancelBtn=new Button("Cancel"); public void init(){ name=new TextField(5); isal=new TextField(5); nsal=new TextField(5); add(prompt1); add(name); add(isal); add(prompt2); add(nsal); add(okBtn); okBtn.addActionListener(this); cancelBtn.addActionListener(this); add(cancelBtn); } public void paint(Graphics g){ g.drawString(msg,0,80); } public void CreateEmp(String empName,double sa){ try{ Emp=new Employee(empName,sa); msg=new String(Emp.toString()); } catch(IllegalSalaryException ise){ msg=new String(ise.toString()); } } public void ChangeEmpSal(double changeSal){ try{ Emp.setEmpSalary(changeSal); msg=new String(Emp.toString()); } catch(IllegalSalaryException illSal){ msg=new String(illSal.toString()); } catch(IllegalSalaryChangeException illSalChange){ msg=new String(Emp.toString()+illSalChange.toString()); } } public void actionPerformed(ActionEvent e){ String empName; double empSal,changeSal; Object obj=e.getSource(); if(obj==okBtn){ empName=new String(name.getText()); if(empName==null){ msg=new String("請先輸出雇員姓名工資並創立之"); } if(nsal.getText()==null){ empSal=Double.valueOf(isal.getText()).doubleValue(); CreateEmp(empName,empSal); } else{ changeSal=Double.valueOf(nsal.getText()).doubleValue(); ChangeEmpSal(changeSal); } } if(obj==cancelBtn){ naem.setText(""); isal.setText(""); nsal.setText(""); } repaint(); } } class Employee{ String m_EmpName; double m_EmpSalary; Employee(String name,double initsalary)throws IllegalSalaryException{ m_EmpName=name;//看這裡有成績沒,參考代碼為m_EmpName=new String(name); if(initsalary<800){ throw(new IllegalSalaryException(this,initsalary));//throw語句 } m_EmpSalary=initsalary; } public String getEmpName(){ return m_EmpName; } public double getEmpSalary(){ return m_EmpSalary; } public boolean setEmpSalary(double newSal) throws IllegalSalaryException,IllegalSalaryChangeException{ if(newSal<800) throw(new IllegalSalaryException(this,newSal)); else if(getEmpSalary()==0.0){ m_EmpSalary=newSal; return true; } else if(Math.abs(newSal-getEmpSalary())/getEmpSalary()>=0.2) throw(new IllegalSalaryChangeException(this,newSal-getEmpSalary())); else{ m_EmpSalary=newSal; return true; } } public String toString(){ String s; s="姓名:"+m_EmpName+"工資: "+m_EmpSalary; return s; } } class IllegalSalaryException extends Exception{ private Employee m_ConcernedEmp; private double m_IllegalSalary; IllegalSalaryException(Employee emp,double isal){ super("工資低於最低工資"); m_ConcernedEmp=emp; m_IllegalSalary=isal; } public String toString(){ String s; s="為雇員供給的工資不正當:雇員:"+m_ConcernedEmp.getEmpName()+"不法工資:"+m_IllegalSalary+"低於最低工資數額800元"; return s; } } class IllegalSalaryChangeException extends Exception{ private Employee m_ConcernedEmp; private double m_IllegalSalaryChange; IllegalSalaryChangeException(Employee emp,double csal){ super("工資更改太年夜"); m_ConcernedEmp=emp; m_IllegalSalaryChange=csal; } public String toString(){ String s; s="為雇員供給的工資更改不正當:雇員:"+m_ConcernedEmp.getEmpName()+"不法更改工資變更:"+m_IllegalSalaryChange+"高於原工資的20%"; return s; } }