Как бы я выбрасывал «необязательное» исключение? - PullRequest
5 голосов
/ 28 октября 2011

У меня есть этот метод, над которым я работаю (я думаю, что это имя), и он, по сути, пытается сопоставить часть строки, а затем вернуть исходную часть строки - ту часть, которая у меня есть, легковещи.Метод имеет тип 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 ]

10 голосов
/ 28 октября 2011

Обычный способ сделать это - написать два метода, один из которых возвращает значение по умолчанию, а другой - исключение.Вы можете сделать один из этих вызовов другим, чтобы избежать дублирования:

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 голос
/ 16 апреля 2015

Еще один способ справиться с необязательными возвращаемыми значениями - использовать класс Optional в Java 8 и позволить вызывающей стороне решить, что делать, если значение отсутствует:

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));
}
1 голос
/ 28 октября 2011

По определению, исключение нарушает нормальный ход программы. Исключение «всплывает» до тех пор, пока кто-то его не перехватит или поток не прекратит работу.

Вы не можете делать то, что пытаетесь, но у вас есть пара вариантов. Вы можете написать «безопасную» версию метода, которая возвращает значение по умолчанию, если ключ не найден, как вы пытаетесь это сделать, и иметь отдельный метод, который будет генерировать исключение, если ключ не найден.

Другим вариантом, если вы сами определили KeyNotFoundException, будет вывод из RuntimeException вместо простого Exception. Затем вы можете удалить объявление throws из сигнатуры вашего метода и не публиковать тот факт, что метод может вызвать исключение.

Вы не можете, однако, вызвать исключение из метода И вернуть значение из метода.

1 голос
/ 28 октября 2011

Вы должны использовать возвращаемые значения или исключения для обозначения состояния ошибки, но не оба одновременно.

Как правило, если вы предполагаете, что что-то может пойти не так, используйте возвращаемое значение, а если ошибка исключительная,бросить исключение (как следует из названия).

0 голосов
/ 28 октября 2011

Нету.метод может закончиться только возвратом значения / конца или возврата;если это void ИЛИ выдать исключение.

Из того, что я понимаю, чего вы хотите достичь, вы можете использовать метод возврата 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();
    }
}
0 голосов
/ 28 октября 2011

А что если вы создадите свое собственное исключение (расширение Exception), в котором будет иметь конструктор, который принимает строку или все, что вы хотите отправить ему (например, код ошибки или оператор)?

Тогда в вашем пользовательском исключении можно использовать метод получения, который будет использоваться для «получения» любого сообщения об ошибке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...