java.lang.Exception与滚动你自己的异常

时间:2008-10-26 04:56:57

标签: java exception class packaging

在什么时候你会创建自己的异常类而不是使用java.lang.Exception? (所有的时间?只有它会在包外使用?只有它必须包含高级逻辑?等等)

10 个答案:

答案 0 :(得分:25)

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

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

答案 1 :(得分: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本身......

答案 2 :(得分:8)

我相信:

catch (Exception e) {
   ...
}

...是一个应该避免的反模式。您可能需要在应用程序中的某个位置使用一个集中的广泛捕获,以记录错误并阻止整个应用程序终止 - 但是将它们分散在willy-nilly周围是不好的。

为什么:

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是繁重的。

答案 3 :(得分:7)

当我想以不同于其他人的方式对待我的例外时。如果我想抓住我的并传播其他人的,或者如果我想抓住其他人并传播我的,或者如果我想抓住两者但是以不同方式对待它们,那么我将为我的异常定义一个单独的类。如果我想对它们进行相同的处理,无论是通过传播它们还是通过捕获它们(并且使用捕获的异常以任何方式做同样的事情),我将使用标准类。

答案 4 :(得分:6)

如果存在语言运行库或库的现有异常,请使用它ELSE创建自己的,并将其记录良好,并且应该在99%的情况下都有效。

答案 5 :(得分:4)

软件捕捉意义。

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

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

当您的程序遇到异常情况时,它几乎总是独一无二的程序。为什么要将您的异常情况强制适应现有的异常?如果它对你的程序来说是独一无二的,那么......好吧......它是独一无二的。这样命名。

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

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

答案 6 :(得分:2)

始终使用常见的异常类启动,然后当需要特别处理它时,更改它。

  1. 第一次创建方法时,只需让异常通过。

  2. 如果有必须处理的异常,那些可以在throws中定义,也可以包装到某些运行时异常或者包装自己的throws异常。在许多情况下我更喜欢运行时异常。从API的角度来看,应该避免定义抛出定义。

  3. 稍后当需要对某个调用者的异常进行特定处理时,请返回并为其创建新的异常。

  4. 关键是要在知道需要之前避免做额外的工作。

答案 7 :(得分:1)

如果某个对象/类/方法出现问题,我无法想象会特别抛出java.lang.Exception。它太通用了 - 如果你不打算创建自己的Exception类,在我看来应该至少在API中有一个更具体的异常类型。

答案 8 :(得分:0)

当异常与API相关时,我会使用Java API中的异常。但是如果出现了我自己的API独有的异常情况,那么我将为它创建一个Exception。例如,如果我有一个Range对象,其中包含两个属性min和max以及不变的min< = max,那么我将创建一个异常InvalidRangeException。

当我编写代码时,这会有所帮助,因为我知道异常的来源是因为我违反了我自己的条件之一或来自Java API的东西。

答案 9 :(得分:-1)

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

新手程序员有一种倾向,就是创建自己的异常类,这样他们就可以使用更能说明错误类型的名称。因此,您将找到类似FTPInitializationException,DAOFactoryException等的类,即使这些异常的处理方式与标准异常不同。这显然是应该避免的反模式。