【建站知識】網(wǎng)站建設(shè)程序異常事件

2022-06-10    分類: 網(wǎng)站建設(shè)

捕獲異常

有些代碼必須捕獲異常,捕獲異常需要進行周密的計劃。

如果某個異常發(fā)生的時候沒有在任何地方進行捕獲,那程序就會終止執(zhí)行,并在控制臺上打印出異常信息,其中包括異常的類型和堆棧的內(nèi)容。對于圖形界面程序(applet和application應(yīng)用程序),在捕獲異常之后,也會打印出堆棧的信息,但程序?qū)⒎祷氐接脩艚缑娴奶幚硌h(huán)中(在調(diào)試基于圖形界面的程序時,最好保證控制臺窗口可見,并且沒有被極小化)。

捕獲一個異常,必須設(shè)置try/catch語句塊,如果在try語句塊中的任何代碼拋出了一個在catch+句中說明的異常類,那么:

1.程序?qū)⑻^try語句塊的其余代碼。

2.程序?qū)?zhí)行catch子句中的處理器代碼。

如果在try語句塊中的代碼沒有拋出任何異常,那么程序?qū)⑻^catch子句。

如果方法中的任何代碼拋出了一個在catch+句中沒有聲明的異常類型,那么這個方法就會立刻退出(期待調(diào)用者為這種類型的異常設(shè)計了catch子句)。

需要注意,try語句中的大多數(shù)代碼都很容易理解:讀取并處理文本行,直到遇到文件結(jié)束符為止。正如在JavaAPI中看到的那樣,read方法有可能拋出一個IOException異常。在這種情況下,將跳出整個while循環(huán),進入catch子句,并輸出堆棧情況。對于一個普通的程序來說,這樣處理異?;旧虾虾跚槔?。還有其他的選擇嗎?

通常,最好的選擇是什么也不做,而是將異常傳遞給調(diào)用者。如果read方法出現(xiàn)了錯誤,就讓read方法的調(diào)用者去操心!如果采用這種處理方式,就必須聲明這個方法可能會拋出一個IOException。

請記住,編譯器嚴(yán)格地執(zhí)行throws說明符。如果調(diào)用了一個拋出已檢查異常的方法,就必須對它進行處理,或者將它傳遞出去。

哪種方法更好呢?通常,應(yīng)該捕獲那些知道如何處理的異常,而將那些不知道怎樣處理的異常傳遞出去。如果想將異常傳遞出去,就必須在方法的首部添加一個throws說明符以便告知調(diào)用者這個方法可能會拋出異常。

仔細(xì)閱讀一下JavaAPI文檔,以便知道每個方法可能會拋出哪種異常,然后再決定是自己處理,還是添加到throws列表。對于后一種情況,也不必猶豫。將異常直接交給能夠勝任的處理器進行處理要比壓制對它的處理更好。

同時請記住,這個規(guī)則也有一個例外。如果編寫一個覆蓋超類的方法,而這個方法又沒有拋出異常,那么這個方法就必須捕獲方法代碼中出現(xiàn)的每一個已檢查異常。不允許在子類的thrws說明符中出現(xiàn)超過超類方法所列出的異常類范圍。

處理異常

假設(shè)在一個Java程序運行期間出現(xiàn)了一個錯誤。這個錯誤可能是由于文件包含了錯誤的信息,或者網(wǎng)絡(luò)連接出現(xiàn)問題造成的,也有可能是因為使用無效的數(shù)組下標(biāo),或者試圖使用一個沒有被賦值引用而造成的。用戶期望在出現(xiàn)錯誤時,程序能夠采用一些理智的行為,如果由于出現(xiàn)錯誤而使得某些操作沒有完成,程序應(yīng)該:返回到一種安全狀態(tài),并能夠讓用戶執(zhí)行一些其他的命令;或者允許用戶保存所有操作的結(jié)果,并以適當(dāng)?shù)姆绞浇K止程序。

要做到這些并不是一件很容易的事情。其原因是檢測(或引發(fā))錯誤條件的代碼通常離那些能夠讓數(shù)據(jù)恢復(fù)到安全狀態(tài),或者能夠保存用戶的操作結(jié)果,并正常地退出程序的代碼很遠(yuǎn)。異常處理的任務(wù)就是將控制權(quán)從錯誤產(chǎn)生的地方轉(zhuǎn)移給能夠處理這種情況的錯誤處理器。為了能夠在程序中處理異常情況,必須研究程序中可能會出現(xiàn)的錯誤和問題,以及哪類問題需要關(guān)注。

1.用戶輸入錯誤

除了那些不可避免的打字錄入外,有些用戶喜歡各行其是,不遵守程序的要求。例如,假設(shè)有一個用戶請求連接一個URL,而語法卻不正確。在程序代碼中應(yīng)該對此進行檢查,如果沒有檢查,網(wǎng)絡(luò)數(shù)據(jù)包就會給出警告。

2.設(shè)備錯誤

硬件并不總是讓它做什么,它就做什么。打印機可能被關(guān)掉了。網(wǎng)頁可能臨時性地不能瀏覽。在一個任務(wù)的處理過程中,硬件經(jīng)常出現(xiàn)問題。例如,打印機在打印過程中可能沒有紙了。

3.物理限制

磁盤滿了,可用存儲空間已被用完。

4.代碼錯誤

程序方法有可能無法正確的執(zhí)行。例如,方法可能返回了一個錯誤的答案,或者錯誤地調(diào)用了其他方法。使用了一個無效的數(shù)組下標(biāo),試圖查找一個在散列表中不存在的數(shù)據(jù)項以及試圖對一個空棧進行退棧操作。

對于方法中出現(xiàn)的錯誤,傳統(tǒng)的處理方式是返回一個特定的錯誤編碼,調(diào)用這個方法的方法對其進行分析。例如,對于一個從文件中讀取信息的方法來說,如果返回值不是標(biāo)準(zhǔn)字符,而是一個-1,則表示文件結(jié)束。這種處理方式對于很多異常狀況都是可行的。還有一種表示錯誤狀況的常用返回值是null引用。當(dāng)希望查詢的參數(shù)不存在時,這個方法就會返回null。

遺憾的是,并不是在任何情況下都能夠返回一個錯誤編碼。有可能無法明確地將有效數(shù)據(jù)與無效數(shù)據(jù)加以區(qū)分。一個返回整型的方法就不能簡單地通過返回-1表示錯誤,因為-1很可能是一個完全合法的結(jié)果。

在Java中,如果某個方法不能夠采用正常的途徑完整它的任務(wù),就可以通過另外一個路徑退出方法。在這種情況下,方法并不返回任何值,而是拋出(throw)一個封裝了錯誤信息的對象。需要注意的是,這個方法將會立刻退出,并不返回任何值。此外,調(diào)用這個方法的代碼也將無法繼續(xù)執(zhí)行,而是,異常處理機制開始搜索能夠處理這種異常狀況的異常處理器(exceptionhandler),異常具有自己的語法和特定的繼承結(jié)構(gòu)。

鼠標(biāo)事件

如果只希望用戶能夠點擊按鈕或菜單,那幺就不需要顯式地處理鼠標(biāo)事件。鼠標(biāo)操作將由用戶界面中的各種組件內(nèi)部處理。然而,如果希望用戶使用鼠標(biāo)畫圖,就需要補貨鼠標(biāo)移動點擊和拖動事件。

當(dāng)用戶點擊鼠標(biāo)按鈕時,將會調(diào)用三個監(jiān)聽器方法:鼠標(biāo)第一次被按下時調(diào)用mousepressed;鼠標(biāo)被釋放時調(diào)用mousereleased;最后調(diào)用mouseclicked。如果只對最終的點擊事件感興趣,就可以忽略前兩個方法。用mouseevent類對象作為參數(shù),調(diào)用getX和gety方法可以獲得鼠標(biāo)被按下時鼠標(biāo)指針?biāo)诘膞和y坐標(biāo)。要想?yún)^(qū)分單擊,雙擊和三擊,需要使用getclickcount方法。

有些用戶界面設(shè)計者喜歡讓用戶采用鼠標(biāo)點擊與鍵盤修飾符組合(例如,control+shift+click)的方式進行操作。我們感覺這并不是一種值得贊許的方式。如果對此持有不同的觀點,可以看一看同時檢測鼠標(biāo)按鍵和鍵盤修飾符所帶來的混亂。

需要注意,在Windows環(huán)境下,使用BUTTON3_DOWN_MASK檢測鼠標(biāo)右鍵(非主要的)狀態(tài)。

當(dāng)鼠標(biāo)在窗口上移動時,窗口將會收到一連串的鼠標(biāo)移動事件。請注意:有兩個獨立的接口mouseListener和mouseMotionListener。這樣做有利于提高效率。當(dāng)用戶移動鼠標(biāo)時,只關(guān)心鼠標(biāo)點擊(clicks)的監(jiān)聽器就不會被多余的鼠標(biāo)移動(moves)所困擾。

動作處理

通常,激活一個命令可以有多種方式,用戶可以通過菜單、擊鍵或工具欄上的按鈕選擇特定的功能。在AWT事件模型中實現(xiàn)這些非常容易:將所有事件 連接到同一個監(jiān)聽器上。例如:假設(shè)blueAction是一個動作監(jiān)聽器,它的actionPerformed方法可以將背景顏色改變成藍色。將一個監(jiān)聽 器對象加到下面幾個事件源上:

·標(biāo)記為Blue的工具欄按鈕

·標(biāo)記為Blue的菜單項

·擊鍵CTRL+B

然后,無論改變背景顏色的命令是通過哪種方式下達的,是點擊按鈕、菜單選擇,還是按下鍵盤,其操作動作都是一樣的。

Swing包提供了一種非常實用的機制來封裝命令,并將它們連接到多個事件源,這就是Action接口。一個動作是一個封裝下列內(nèi)容的對象:

·命令的說明(一個文本字符串和一個可選圖標(biāo));

執(zhí)行命令所需要的參數(shù)(例如,在列舉的例子中請求改變的顏色)。

第一個方法是ActionListener接口中很熟悉的一個:實際上,Action接口擴展于ActionListener接口,因此,可以在任何需要ActionListener對象的地方使用Action對象。

接下來的兩個方法允許啟用或禁用這個動作,并檢查這個動作當(dāng)前是否啟用。當(dāng)一個連接到菜單或工具欄上的動作被禁用時,這個選項就會變成灰色。

putValue和getvalue方法允許存儲和檢索動作對象中的任意名/值。有兩個重要的預(yù)定義字符串:Action.NAME和Action.sMALLjcON,用于將動作的名字和圖標(biāo)存儲到一個動作對象中。

如果動作對象添加到菜單或工具欄上,它的名稱和圖標(biāo)就會被自動地提取出來,并顯示在菜單項或工具欄中。SHORT_DESCRiRTION值變成了工具提示。

Action接口的最后兩個方法能夠讓其他對象在動作對象的屬性發(fā)生變化時得到通告,尤其是菜單或工具欄處罰的動作。例如,如果增加一個菜單,作為動作 對象的屬性變更監(jiān)聽器,而這個動作對象隨后被禁用,菜單就會被調(diào)用,并將動作名稱變?yōu)榛疑?。屬性變更監(jiān)聽器是一種常用的構(gòu)造形式,它是JavaBeans 組件模型的一部分。

需要注意,Action一個接口,而不是一個類。實現(xiàn)這個接口的所有類都必須實 現(xiàn)剛才討論的7個方法。慶幸的是,有一個類實現(xiàn)了這個接口除actionPerformed方法之外的所有方法,它就是AbstractAction個類 存儲了所有名/值對,并管理著屬性變更監(jiān)聽器。我們可以直接擴展AbstractAction類,并在擴展類中實現(xiàn)actionPerformed方法。

構(gòu)造器讀取動作的名稱和圖標(biāo),為工具提示設(shè)置簡要說明,將工作設(shè)置為監(jiān)聽器。

最后,想要將這個動作對象添加到擊鍵中,以便讓用戶敲擊鍵盤命令來執(zhí)行這項動作。為了將動作與擊鍵關(guān)聯(lián)起來,首先需要生成KeyStroke類對象。這 是一個很有用的類,它封裝了對鍵的說明。要想生成一個Keystroke對象不要調(diào)用構(gòu)造器,而是調(diào)用KeyStroke類中的靜態(tài) getKeyStroke方法:

為了能夠理解下一個步驟,需要知道keyboardfocus的概 念。用戶界面中可以包含許多按鈕、菜單、滾動欄以及其他的組件。當(dāng)用戶敲擊鍵盤時,這個動作會被發(fā)送給擁有焦點的組件。通常具有焦點的組件可以明顯地察覺 到(但并不總是這樣),例如,在Java觀感中,具有焦點的按鈕在按鈕文本周圍有一個細(xì)的矩形邊框。用戶可以使用TAB鍵在組件之間移動焦點。當(dāng)按下 SPACE鍵時,就點擊了擁有焦點的按鈕。還有一些鍵執(zhí)行一些其他的動作,例如,按下箭頭鍵可以移動滾動條。

然而,在這里的示例中,并不希望將擊鍵發(fā)送給擁有焦點的組件。否則,每個按鈕都需要知道如何處理CTRL+Y、CTRL+B和CTRL+R這些組合鍵。

這是一個常見的問題,Swing設(shè)計者給出了一種很便捷的解決方案。每個JComponent有三個輸入映射(imput maps),每一個映射的KeyStroke對象都與動作關(guān)聯(lián)。

事件處理基礎(chǔ)

對于圖形用戶界面的程序來說,事件處理是十分重要的。要想實現(xiàn)用戶界面,必須掌握J(rèn)ava事件處理的基本方法。

任何支持GUI的操作環(huán)境都要不斷地監(jiān)視敲擊鍵盤或點擊鼠標(biāo)這樣的事件。操作環(huán)境將這些事件報告給正在運行的應(yīng)用程序。如果有事件產(chǎn)生,每個應(yīng)用程序?qū)? 決定如何對它們作出響應(yīng)。在VisualBasic這樣的語言中,事件與代碼之間有著明確的對應(yīng)關(guān)系。程序員對相關(guān)的特定事件編寫代碼,并將這些代碼放置 在過程中,通常人們將它們稱為事件過程(event procedure)。例如,有一個名為HelpButton的VisualBasic按鈕有一個與之關(guān)聯(lián)的HelpButton_Click時間過程。 這個過程中的代碼將在點擊按鈕后執(zhí)行。每個VisualBasic的GUI組件都響應(yīng)一個固定的事件集,不可能改變VisualBasic組件響應(yīng)的事件 集。

另一方面,如果使用像原始的C這樣的語言進行事件驅(qū)動的程序設(shè)計,那就需要編寫代碼來 不斷地檢查事件隊列,以便查詢操作環(huán)境報告的內(nèi)容(通常這些代碼被放置在包含很多switch語句的循環(huán)體申)。顯然,這種方式編寫的程序可讀性很差,而 且在有些情況下,編碼的難度也非常大。它的好處在于響應(yīng)的事件不受限制,而不像VisualBasic這樣的語言,將事件隊列對程序員隱藏起來。

Java程序設(shè)計環(huán)境折中了VisualBasic與原始C的事件處理方式,因此,它既有著強大的功能,又具有一定的復(fù)雜性。在AWT所知的事件范圍 內(nèi),完全可以控制事件從事件源(event source)例如,按鈕或滾動條,到事件監(jiān)聽器(event listener)的傳遞過程,并將任何對象指派給事件監(jiān)聽器。不過事實上,應(yīng)該選擇一個能夠便于響應(yīng)事件的對象。這種事件委托模型(event delegation model)與VisualBasic那種預(yù)定義監(jiān)聽器模型比較起來更加靈活。

事件源有一些向其注冊事件監(jiān)聽器的方法。當(dāng)某個事件源產(chǎn)生事件時,事件源會向為事件注冊的所有事件監(jiān)聽器對象發(fā)送一個通告。

像Java這樣的面向?qū)ο笳Z言,都將事件的相關(guān)信息封裝在一個事件對象(event object)中,在Java中,所有的事件對象都最終派生于java.util.EventObject類。當(dāng)然,每個事件類型還有子類,例 如,ActionEvent和WindowEvent。

不同的事件源可以產(chǎn)生不同類別的事件。例如,按鈕可以發(fā)送一個ActionEvent對象,而窗扣可以發(fā)送WindowEvent對象。

綜上所述,下面給出AWT事件處理機制的概要:

監(jiān)聽器對象是一個實現(xiàn)了特定監(jiān)聽器接口(listener interface)的類的實例。

事件源是一個能夠注冊監(jiān)聽器對象并發(fā)送事件對象的對象。

當(dāng)事件發(fā)生時,事件源將事件對象傳遞給所有注冊的監(jiān)聽器。

監(jiān)聽器對象將利用事件對象中的信息決定如何對事件做出響應(yīng)。

本文名稱:【建站知識】網(wǎng)站建設(shè)程序異常事件
路徑分享:http://www.muchs.cn/news27/165927.html

網(wǎng)站建設(shè)、網(wǎng)絡(luò)推廣公司-創(chuàng)新互聯(lián),是專注品牌與效果的網(wǎng)站制作,網(wǎng)絡(luò)營銷seo公司;服務(wù)項目有網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都app開發(fā)公司