2009-10-29 50 views
2

當我們得到一個實際上是例外的對象時,我們可以用他們做任何我們可以用我們的語言中的普通對象做的事情。我們可以將它們作爲參數傳遞,我們可以將它們存儲在某個集合中,最糟糕的是,我們可以通過這些方法返回它們!爲什麼很多語言將Exception對象視爲一等公民?

所以有可能有人寫臭這樣的代碼:

public Exception doSomethingCritical() 
{ 
    Exception error = null; 

    try 
    { 
     ... 
    } 
    catch (Exception e) 
    { 
     // maybe at least here is the logging of the error if we are lucky 
     error = e; 
    } 
    return error; 
} 

所以,問題是爲什麼是一個例外對象的概念在許多面向對象語言一流的公民?如果我們只允許異常對象(如throw)允許的語言中有限的構造,可能會更好。

+4

有時候比依靠人們的判斷來防止愚蠢的用法更爲複雜。錘子是用來驅動釘子的,但是我不能阻止人們將它用於其他目的......如果我嘗試,它會花費我。 – jldupont 2009-10-29 13:18:45

+1

我真的不想聽到嗤之以鼻的聲音,但它有什麼關係?我想我想知道這會帶來什麼問題? – MattC 2009-10-29 13:19:44

+0

問題是異常有解決報告錯誤的問題作爲方法的返回值(如在C中)。所以你可以忘記看結果而完全忽略它。 – 2009-10-29 13:34:43

回答

1

我的看法。

我認爲你混淆了兩個不同的東西:異常和異常投擲。

異常拋出是一種帶外過程,允許您通過優先橫向通道拋出一個對象。這個對象可以被攔截並通過異常捕獲機制來處理。

異常只是一個對象,你可以(優先)通過異常拋出帶外通道拋出。當然,這個通道可以具有被引發對象接口的必要條件,Exception類接口滿足的必備條件。

您正在看另一個問題。事實上,你可以做恐怖事件,但Exception對象沒有什麼特別之處,除了是帶外通道中拋出的首選對象之外。

+0

真的很好觀點。我希望所有的程序員都能以這種方式理解異常。但是,我們能用這種語言做些什麼嗎? – 2009-10-29 14:46:27

+0

從技術上講,你可以,但是你必須爲異常對象創造額外的語義,使其不是一個類,而是另一個不是類的東西。沒有人願意這樣做,因爲你使語言核心更復雜,更不靈活。基本上,鬆散的情況。 – 2009-10-30 04:39:17

+0

這將違背考慮「一切爲對象」的(良好)趨勢。例如在python中,這非常普遍,以至於類,模塊,異常,函數(命名和匿名),數據類型都是對象。 – 2009-10-30 04:43:15

0

因爲這樣的生活很容易。除此之外,這意味着異常對象可以包含程序可以用來糾正異常情況的信息(可能需要人工干預)。

Abend是如此的20世紀60年代。

0

我不確定您提供的示例是否足夠強大,沒有異常作爲對象。畢竟,你可以在編程時做各種「臭」或「壞」的事情。但這正是我們想要優秀程序員的原因。只是因爲我可以做點什麼:

def get_total 
    return nil 
end 

肯定並不意味着我不應該允許nil作爲一個對象的實例!

+0

爲什麼這麼「肯定」? ;-)也許某種語言可能不允許任何對象爲零,但允許它用於某些特殊情況,這將是很好的。 – 2009-10-29 13:24:13

1

如果他們不是第一類公民,您將如何從基礎異常類繼承併爲模塊派生自己的異常類?

6

將異常視爲一種特殊情況,只允許有限的功能和例外情況的問題是,最終某處每個好程序都需要執行有異常,無論是全局錯誤處理程序還是有限項目適當處理例外情況。通過使一等公民例外,有許多好處,例如:

  • 允許例外的子類化。這對於異常處理非常有用,因爲處理異常的代碼可以縮小範圍,只處理他們知道如何處理的異常。我甚至可以說任何捕捉「Exception」的非全局異常處理例程可能是錯誤的。
  • 傳遞數據以及異常。如果您在catch語句邏輯中唯一知道的異常發生,那麼異常並不是非常有用。對於某些異常類型,堆棧跟蹤,消息甚至自定義數據在識別和解決導致異常的問題方面是非常有用的。
  • 創建使用OOP本身的錯誤處理例程。如果異常不能作爲對象傳遞,你不可能有一個處理異常的庫 - 至少不是寫得很好的庫。

除此之外,沒有辦法像上面發佈的那樣防範不良異常處理。即使一個例外不是一等公民,也沒有辦法阻止開發者吃任何和所有的例外,並且進行他們的快樂方式(至少在沒有根本打破我們如何看待例外的情況下)

+1

訪問類結構是一個很重要的部分。捕捉IOException一段時間,看看它是如何有用的捕捉整個類別的錯誤。 是的,你可以用其他方式做,但爲什麼要重新發明輪子? – 2009-10-29 13:30:51

2

我'我從來沒有見過你用過的例子。我不能看不能讓人們如何返回異常都會有很大的不同在概念可憐的代碼 - 比較

public int doSomethingCritical() 
{ 
    int error = 0; 

    try 
    { 
     ... 
    } 
    catch (Exception e) 
    { 
     // maybe at least here is the logging of the error if we are lucky 
     error = E_SOMETHINGBAD; 
    } 
    return error; 
} 

而如果你創建了一種新的用於例外「東西」是ISN」如同一個物體一樣,有一個設計和學習開銷的缺點。

+0

非常好的一點。我認爲,在一種不允許異常作爲返回值的語言中,我的示例看起來完全像這樣。 – 2009-10-29 14:37:36

1

我不明白爲什麼我不應該被允許作爲正常的方法參數傳遞和返回異常。如果我正在編寫異常處理庫,該怎麼辦?如果我正在編寫一個比較異常的單元測試斷言呢?

相關問題