2008-10-26 56 views

回答

25

我认为你需要问自己一个非常不同的问题“创建一个新的例外给我或开发者谁使用我的代码?“真的,它给你或其他人的唯一好处是能够处理异常。这似乎是一个明显的答案,但事实并非如此。您应该只处理可以合理恢复的异常。如果你抛出的异常是一个真正致命的错误,为什么会给开发人员一个错误处理它的机会?

更深入的讨论:Custom exceptions: When should you create them?

+3

如果您不想混淆用户,也可以创建一个。java.lang.Exception可能意味着一些可能出错的事情AppFileNotFound(sFilePath) - 有助于减少在布什附近的跳动... – Gishu 2008-10-26 05:36:32

7

当我想从其他人的区别对待我的异常。如果我想抓住我的并宣传其他人的话,或者如果我想抓住别人的并传播我的想法,或者如果我想抓住两者但以不同的方式对待他们,那么我会为我的例外定义一个单独的类。如果我想把它们都对待,无论是通过传播还是通过捕获两者(并以捕捉到的异常来做同样的事情),我将使用标准类。

-1

在大多数情况下,创建您自己的异常类是没有意义的。

新手程序员有一种倾向,即创建自己的异常类,以便他们可以使用更能表明错误类型的名称。所以你会发现像FTPInitializationException,DAOFactoryException等类,即使这些异常的处理方式与标准异常不同。这显然是应该避免的反模式。

+0

建议程序员抛出java.lang.Exception远比抛出自己的类比扩展java.lang.Exception;有很多异常会导致j.l.Exception不应被捕获。 – janm 2008-10-26 13:49:42

+0

Downvoted。人们可以直接抛出“RuntimeException”而无需子类化,因为调用者无法恢复。但是当你抛出“异常”时,你期望调用者能够恢复。但是,如果你不给他们一个特定的子类,他们如何有足够的上下文来恢复? – benjismith 2011-11-13 18:24:59

2

始终通过使用常见的异常类开始,然后当需要出现专门处理它时,请对其进行更改。

  1. 首次创建方法时,只需让异常通过即可。

  2. 如果有必须处理的异常,那么可以只是在throws中定义或者包装到某个运行时异常或包装自己的throws异常。在很多情况下我更喜欢运行时异常。应该避免定义投掷定义,直到从API的角度来看需要它。

  3. 后来,当某个需求似乎对某个调用者中的异常做特定的处理时,回来并为其创建新的异常。

重点是在知道需要什么之前避免做额外的工作。

+1

Exception类是特殊的; “catch(Exception e)”会捕获所有你可能不应该捕捉的东西。 – janm 2008-10-26 13:48:02

6

如果语言运行时或库存在现有的异常,则使用它,否则创建自己的文档,并将其记录到文档中,并且应该在99%的情况下工作。

11

原因一:

需要捕捉特定的东西。如果调用代码需要处理特定的异常情况,则需要区分异常,并且Java将异常与不同类型区分开来,因此您需要编写自己的异常。

基本上,如果有人写:

catch(ExistingException e) { 
    if({condition}) { 
    { some stuff here} 
    } 
    else { 
    { different stuff here} 
    } 
} 

你可能想要写一个特定的扩展; catch异常匹配比条件更清晰,恕我直言。

记住:你的新的异常可以 RuntimeException的

原因二的

一个子类:

API整合。如果你写一个接口,你有几个实现,这是可能的,他们将调用不同的API与抛出一大堆不同的非RuntimeExceptions的:

interface MyInterface { 
    void methodA(); 
} 

class MyImplA { 
    void methodA() throws SQLException { ... } 
} 

class MyImplB { 
    void methodA() throws IOException { ... } 
} 

你真的想MyInterface.methodA到抛出SQLException和IOException异常?也许那么在自定义异常中包装可能的异常是有意义的。这又可以是RuntimeException。或者甚至是RuntimeException本身...

0

当异常涉及API时,我会使用Java API中的异常。但是,如果出现一种特殊情况,这对我自己的API来说是独一无二的,那么我将为它创建一个例外。例如,如果我有一个具有两个属性min和max的Range对象,并且不变量min < = max,那么我将创建一个异常InvalidRangeException。

当我编写代码时,这有助于我知道是否因为我违反了我自己的条件之一或来自Java API的某个东西而发生异常。

8

笔者认为:

catch (Exception e) { 
    ... 
} 

...是应该避免的反模式。您可能希望在应用程序中的某处集中广泛地捕获,记录错误并防止整个应用程序终止 - 但让它们散落在无处不在的地方是很糟糕的。

为什么:

try { 
    if(myShape.isHidden()) { 
     throw new Exception(); 
    } 
    // More logic 
} catch (Exception e) { 
    MyApp.notify("Can't munge a hidden shape"); 
} 

所以,你试试这个,而且由于一个编码错误,是MyShape的空。运行时试图揭示myShape时引发NullPointerException。此代码报告一个隐藏的形状,当它应该报告一个空指针。

要么你自己的例外,要么在API中找到适当特殊的例外。这并不像扩展Exception或RuntimeException那样繁重。

1

如果某个对象/类/方法有问题,我无法想象如何特别抛出java.lang.Exception。这太泛化了 - 如果你不打算创建自己的Exception类,在我看来,至少应该是API中更具体的Exception类型。

4

软件捕捉含义。

抛出现有异常几乎没有理由:JVM已经为您做了这件事。你的异常版本并不准确,抛出“异常”也没有意义。

由于您编写的解析算法,您可能有一个DataFormatException。然而,这很少见。

当您的程序遇到异常情况时,它对于您的程序几乎总是唯一的。为什么迫使您将特殊情况融入现有的异常?如果它对你的程序来说是独一无二的,那么......好吧......它是独一无二的。这样命名。

但是,不要为每个唯一的消息提供唯一的异常类。一个例外可以具有许多变体消息和支持细节。

翻译为Java的Python经验法则是在包级别定义任何唯一的异常。 [在Python中,他们建议在“模块”级别有例外,这种情况不能精确地转化为Java。]