繁体   English   中英

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

[英]Java Exception handling when arguments are hard-coded

关于在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用户期望并捕获该错误。

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

我做这样的事情:

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

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

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

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

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

这样,您的异常将不会隐藏,如果它发生也不会,您的API用户必须满足它。

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

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

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

我通常遵循这个问题的其他答案概述的策略(比如将已检查的异常软化为RuntimeException )。 但是,一个有趣的替代方法是使用断言:

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

当使用-ea JVM标志启用AssertionError如果抛出UnsupportedEncodingException ,则此方法将抛出AssertionError 烦恼是需要返回一个值(如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)子句(它是否会发生)。

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM