如何抛出“可选”异常?

时间:2011-10-28 18:12:25

标签: java exception-handling

我有这个方法我正在研究(我认为这就是名字),它本质上试图匹配一个字符串的一部分,然后返回字符串的前一部分 - 我已经得到的部分,很容易东西。该方法的类型为String。

当我的方法无法在字符串中找到模式时,我希望它返回一个空字符串。我还想发一些带有空字符串的东西去“嘿,我没找到你的钥匙”,但我希望这是可选的。

这基本上就是我想要的方法:

public static String getKey(String key) throws KeyNotFoundException {
    if (key.equals("something")) {
        return "great";
    } else {
        throw new KeyNotFoundException();
        return "";
    }
}

但是这段代码的问题在于return "";显然无法访问throw new KeyNotFoundException();

如果我打算调用此方法,我必须使用try {} catch(KeyNotFoundException knf) {}块。这是我想要选择的块。

如果我选择忽略未找到密钥的事实(例如,不要使用try catch),那么我只想在返回时获得空字符串。

但是如果我需要知道是否找到了正确完成操作的密钥,我还希望能够用try-catch块包围它。

我认为我的方法不对,但我似乎无法找到替代方案(Java的新手),有人可以对此有所了解吗?

6 个答案:

答案 0 :(得分:10)

执行此操作的常用方法是编写两个方法,一个返回默认值,另一个抛出异常。您可以让其中一个调用另一个,以避免重复:

public static String getKey(String key) throws KeyNotFoundException {
    String value = getOptionalKey(key);
    if (value.equals("")) throw new KeyNotFoundException(key);
    return value;
}

public static String getOptionalKey(String key) {
    if (key.equals("something")) {
        return "great";
    } else {
        return "";
    }
}

然后,呼叫者可以根据需要选择呼叫哪个:

String value = getOptionalKey("uma"); // oblivious

try {
    String value = getKey("uma"); // cognisant
}
catch (KeyNotFoundException e) {
    // panic
}

答案 1 :(得分:1)

您应该使用返回值或异常来表示错误条件,但不能同时使用两者。

通常,如果您预计某些内容可能出错,请使用返回值,如果错误是异常,则抛出异常(顾名思义)。

答案 2 :(得分:1)

根据定义,异常会破坏正常的程序流程。例外情况“冒泡”,直到有人抓住它或线程终止。

你不能完全按照自己的意思去做,但你有几个选择。您可以编写方法的“安全”版本,如果找不到密钥则返回默认值,就像您正在尝试的那样,并且如果找不到密钥,则会有一个单独的方法抛出异常。

如果您自己定义KeyNotFoundException,另一个选项是从RuntimeException而不是简单地Exception派生。然后,您可以从方法签名中删除throws声明,而不发布该方法可能引发异常的事实。

但是,您不能从方法中抛出异常并从方法中返回一个值。

答案 3 :(得分:1)

您可以处理可选返回值的另一种方法是使用Java 8的Optional类,并让调用者决定在该值不存在时该怎么做:

public static Optional<String> getOptionalKey(String key) {
    if (key.equals("something")) {
        return Optional.of("great");
    } else {
        return Optional.empty();
    }
}

您可以将其与其他答案中讨论的多种方法相结合:

public static String getKey(String key) throws KeyNotFoundException {
    return getOptionalKey(key).orElseThrow(() -> new KeyNotFoundException(key));
}

答案 4 :(得分:0)

如果你创建自己的异常(扩展异常),它将有一个构造函数,它接受一个String或你想发送给它的任何东西(如错误代码或语句)?

然后,您可以在自定义异常中使用getter方法,该方法将用于“获取”任何错误消息。

答案 5 :(得分:0)

没了。一个方法只能以返回值/结束或返回结束;如果它是无效的或抛出异常。

根据我对你想要实现的内容的理解,你可以使用void返回方法并在参数中提供特殊对象的引用。然后,您可以将此对象的字段设置为您想要“返回”并抛出异常的结果。

这样的东西
class final ResultHoder {
  String result;
  public void setResult(String result) {
    this.result = result;
  }
  public String getResult() {
    return this.result;
  }
}


public static void getKey(String key, ResultHolder result) throws KeyNotFoundException {
    if (key.equals("something")) {
        result.setResult("great");
        return;
    } else {
        result.setResult("");
        throw new KeyNotFoundException();
    }
}