简体   繁体   中英

How would I go about throwing an “optional” exception?

I've got this method I'm working on (I think that's the name) and it essentially tries to match a part of a string and then return the proceeding part of the string - that part I've got, easy stuff. The method is of type String.

When my method fails to find the pattern in the string I want it to return an empty string. I also want to send something along with the empty string to go "hey, I didn't find your key" but I want this to be optional.

This is essentially what I want the method to do:

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

But the problem with this code is that the return ""; is obviously unreachable due to throw new KeyNotFoundException(); .

If I was going to call this method I'd have to use the try {} catch(KeyNotFoundException knf) {} block. It's this block that I want to make optional however.

If I choose to be oblivious to the fact the key was not found (eg don't use try catch) then I just want to be given the empty string on return.

But I also want to be able to surround it with a try-catch block if I need to know whether the key was found for my operation to complete correctly.

I think I'm going about this the wrong way but I can't seem to figure out an alternative (new to Java), could anyone shred some light on this please?

The usual way to do this would be to write two methods, one which returns a default value, and one which throws an exception. You can have one of these call the other, to avoid duplication:

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 "";
    }
}

The caller can then choose which one to call, based on their needs:

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

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

Another way you could deal with optional return values is to use Java 8's Optional class, and let the caller decide what to do when the value is not present:

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

You could combine it with the multiple methods approach discussed in other answers:

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

You should either use return values or exceptions to denote an error condition, but not both.

Generally, if you anticipate that something can go wrong, use a return value, and if the error is exceptional, throw an exception (as the name suggests).

By definition, an exception disrupts the normal program flow. The exception "bubbles up" until someone catches it or the thread terminates.

You can't do exactly what you're trying, but you have a couple options. You could write a "safe" version of the method that returns a default value if the key isn't found, like you're trying to do, and have a separate method that will throw the exception if the key isn't found.

Another option, if you've defined KeyNotFoundException yourself, would be to derive from RuntimeException instead of simply Exception . Then, you could remove the throws declaration from your method signature and not publish the fact that the method could throw an exception.

You can't, however, throw an exception from the method AND return a value from the method.

What about if you create your own Exception (extend Exception) which will have a constructor that takes a String or whatever you want to send to it (like error code or statement)?

Then you can have a getter method within your Custom Exception that will be used to "get" whatever the error message was.

nope. a method can only end with returning a value/end or return; if it is void OR throw an exception.

From what I understand of what you want to achieve, you could use a void returning method and provide a reference of a special object in argument. you would then set a field of this object to the result you want to 'return' and throw the exception.

Something like

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();
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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