【问题标题】:Java - Simple exception handling queryJava - 简单的异常处理查询
【发布时间】:2012-03-26 20:15:26
【问题描述】:

只是一个简单的问题,我似乎无法在网上找到正确的答案。

当我有一个 try/catch 块并且我想捕获一个错误时,我应该使用 System.err.println(...) 还是应该使用 throw new Exception(...)

例如:

if (null==userList || null==credentials)
    System.err.println("Did you call login() first?");
else
{
    try
    {
        currentUser=(String) userList.nextElement();
        currentPass=(String) credentials.get(currentUser);          
    }
    catch(NoSuchElementException nsee)
    {
        System.err.println("Is properties file blank?");
        //Or should this be
        throw new NoSuchElementException("Is properties file blank?");
        nsee.printStackTrace();
    }
}

编辑:那么throw 不是要进入catch 吗?我可以使用throw 而不是catch 还是仅用于方法签名? 在这种情况下捕获错误的正确方法是什么,我将尝试确保属性文件不是空白并且包含值? 另外,为了清楚起见,我的目标是让用户尽可能清楚错误是什么,以便他们立即知道他们需要修复他们的属性文件。

【问题讨论】:

  • 我认为它们是不同的问题 - System.err 主要用于调试
  • 一个奇怪的问题。重新抛出的决定似乎与您是否要记录它或要记录它的位置无关。

标签: java exception throw


【解决方案1】:

取决于你想做什么。

如果您的方法的合同无法履行,以防出现异常(例如,您无法返回您想要的值)抛出一个新的异常。 (但请注意,仅仅重新抛出一个新异常并没有多大意义。只需将该方法声明为 throws NoSuchELementException 并让异常传播。)

如果您的合同可以履行以防出现异常(即,如果未找到任何元素,您可以返回 null)那么您应该捕获异常(如果您使用 System.err.println 记录它like) 然后继续执行。


关于抛出新异常的第一个选项的旁注:

您应该始终抛出一个适合当前抽象级别的异常。例如,如果该方法被称为getUserFromList(...),并且由于某些与集合相关的问题而遇到NoSuchElementException,则应捕获异常并抛出NoSuchUserException

突出区别:

try {
    currentUser=(String) userList.nextElement();
    currentPass=(String) credentials.get(currentUser);          

} catch(NoSuchElementException nsee) {
              ^^^^^^^

    System.err.println("Is properties file blank?");
    throw new NoSuchUserException("Is properties file blank?");
                    ^^^^
}

【讨论】:

    【解决方案2】:

    这取决于你的目标是什么。如果您的目标是为解释日志的任何人提供更多上下文,那么您可以链接异常,将其包装在更特定于域的异常中。

    例如,您可以创建一个名为 ConfigurationException 的运行时异常,然后像这样重新抛出它:

    } catch(NoSuchElementException nsee) {
       throw new ConfigurationException("Expected non-blank properties file", nsee);
    }
    

    通常,最好不要直接登录到System.err(因为您的用户可能不会查看它),而是配置一个日志框架(log4j、slf4j、Java Logging API 等)。然后,您可以根据需要配置记录器以附加到错误流。

    【讨论】:

      【解决方案3】:

      这取决于你想做什么。

      如果你重新抛出异常,函数将退出,异常将被重新捕获到调用堆栈的更远位置。

      如果只打印堆栈跟踪,则将控制权返回给函数,您可以继续执行。

      以下内容虽然没有意义:

      try
      {
          currentUser=(String) userList.nextElement();
          currentPass=(String) credentials.get(currentUser);          
      }
      catch(NoSuchElementException nsee)
      {
          throw new NoSuchElementException("Is properties file blank?");
      }
      

      如果你没有捕捉到异常,调用上下文无论如何都要对它负责。除非您明确想要更改字符串,否则这样做是没有意义的。

      【讨论】:

        【解决方案4】:

        这取决于你想做什么。 如果您只需要有关捕获异常的信息[例如:用于日志记录,那么 syserr 对您来说就足够了。 但是如果你想处理这个异常,你应该把它扔到上层并在那里处理它或者在 catch 块内处理它。 在你的情况下,你应该通过发回一些关于获取用户名/密码失败的信息来处理它。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-05-27
          相关资源
          最近更新 更多