参数是硬编码时的Java异常处理

时间:2012-12-16 10:21:10

标签: java api exception

我对使用Java创建API有疑问。假设我有一个课程如下: -

class Test
{
  public final static String DEFAULT_ENCODING = "utf-8";

  public byte[] encodeIt(String input)
  {
    try {
      return input.getBytes(DEFAULT_ENCODING);
    } catch(UnsupportedEncodingException e) {
      // do something
    }
  }
}

我知道UnsupportedEncodingException永远不会出现,因为我使用静态字符串作为toBytes的输入。让encodeIt执行throws UnsupportedEncodingException是没有意义的,因为我不希望API用户期望并捕获该错误。

在这种情况下,最好的做法是设置空挡块吗?

6 个答案:

答案 0 :(得分:5)

我这样做:

public byte[] encodeIt(String input) {
    try {
        return input.getBytes(DEFAULT_ENCODING);
    }
    catch (UnsupportedEncodingException e) {
        throw new ShouldNeverHappenException(e);
        // or: throw new IllegalStateException(e);
    }
}

(当然,ShouldNeverHappenException是运行时异常)。

这样,如果有人碰巧更改了常量值,或者添加了编码参数,该方法将快速失败,并且问题不会被忽视或隐藏在日志文件中。

答案 1 :(得分:5)

拥有空的catch块是一个坏主意。即使你的推理看起来是正确的,这个设计在某个阶段会导致你无休止的调试和搜索,一旦异常开始发生,你的代码就会吞下它们。我会把你的异常包装在RuntimeException中并抛出它。像这样:

public encodeIt(String input)
  {
    try {
      return input.getBytes(DEFAULT_ENCODING);
    catch(UnsupportedEncodingException e) {
      throw new RuntimeException(e);
    }
  }

这样一来,如果您的异常发生,您的异常就不会隐藏,也不会让您的API用户满足它。

答案 2 :(得分:3)

  

在这种情况下,最好的做法是设置空挡块吗?

我觉得这不是一个好主意。空捕获块意味着可能发生某些事情,你永远不会知道。

不要抛出此异常。抓住并记录它,这样你就可以检查你的假设它永远不会发生,但至少你会知道它是否永远不会到来。

答案 3 :(得分:2)

我通常会遵循此问题的其他答案所概述的策略(例如将已检查的异常软化为RuntimeException)。但是,一个有趣的选择是使用断言:

public byte[] encodeIt(String input)
{
  try {
    return input.getBytes(DEFAULT_ENCODING);
  } catch(UnsupportedEncodingException e) {
    assert false;
    return null;
  }
}

当使用-ea JVM标志启用断言时,如果抛出AssertionError,此方法将抛出UnsupportedEncodingException。烦恼是需要返回一个值(例如null),否则代码将无法编译。

所以也许以下是“更好”:

public byte[] encodeIt(String input)
{
  try {
    return input.getBytes(DEFAULT_ENCODING);
  } catch(UnsupportedEncodingException e) {
    throw new AssertionError("Unexpected.", e);
  }
}

除了RuntimeException很好地自我记录之外,与抛出AssertionError并没有太大的不同。并且,作为Error的子类,它代表了比Exception通常所暗示的更基本的失败。没有机会在处理这个东西的堆栈上某个更高的catch (Exception e)子句(它是否会发生)。

答案 4 :(得分:1)

我认为最好的方法是避免检查异常。只需使用未经检查的。然后你将充分利用2个世界:如果确实发生错误,你会发出错误的信号,你不会强迫API的用户处理异常。

答案 5 :(得分:0)

如果您非常非常确定它永远不会发生,请留下一个空的挡块。 但是对于练习,以防万一你以后更改代码,最好在发生异常时将其记录到控制台。