Java - где и как исключения должны использоваться?

А-ч, я нашел решение: используйте стиль regex для показа пространства:

RewriteRule ^article/with\sspaces.html$ ...

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

10
задан Michael Myers 7 December 2009 в 17:46
поделиться

9 ответов

Существует исключение, поэтому программисту Задачи не нужно решать проблему самостоятельно. (1): В случае, если проблема НЕ ЛОГИЧНА для его решения в Задаче. Задача чтения String из потока не должна обрабатывать дисковую ошибку, не так ли. Но это должно быть очень логично для обработки, если данные не содержат String.

(2): Он не может обработать это сам (недостаточно информации) Задача чтения строки из файла и файла, который не найден, может попросить пользователя выбрать другой файл, но как задача теперь, в какой папке может быть файл, какое расширение может быть. Не зная этого, как задача может создать графический интерфейс, чтобы повторно спросить об этом.

(3): Нет логического (или управляемого) способа различать разные результаты. If a task can't read the file and return null. What about if the file in the wrong format, return null too? How can these two differ? Exceptions can be used to differ that. That why it is called an Exception :-D.

(4): There are many similar tasks that need similar handling and writing that in all tasks is hard to maintain. Writing the handle code for all access can be a mess as you may require many duplications.


interface DBAccess {
    public Result accessDB();
}

class DBOperation {
    static public void DoOperation(DBAccess pAccess) {
        try { return DBAccess.accessDB(); }
        catch(InvalidDBPasswordException IPE) {
             // Do anything about invalid password
        }
        catch(DBConnectionLostException DBCLE) {
             // Do anything about database connection lost
        }
        // Catch all possible DB problem
    }
}

...

private User[] ShowUserList_and_ReturnUsers() {
    // Find the used.

    // Show user list

    if (Users.count() == 0)
         return null;
    else return Users;

    // No need to handle DB connection problem here
}
private User[] GetUserProfile() {
    // Find the used and return
    // No need to handle DB connection problem here
}
...

/** An onClick event to show user list */ {
    DBOperation.DoOperation(new DBAccess() {
        public Result accessDB() {
            return ShowUserList_and_ReturnUsers();
        }
    });
}
/** An onClick event to show a user profile */ {
    DBOperation.DoOperation(new DBAccess() {
        public Result accessDB() {
            return GetUserProfile();
        }
    });
}
... Many more DB access

(5): Writing all the checking for error complicate or slow down the task. The above problem should show how can it help reduce the complication. Here is how it help not to slow down.



for(int i = 0; i < Users.length; i++) {
    User aUser = Users[i];
    // Do something with user
}

Replaced with

try {
  for(int i = 0; ; i++) {
      User aUser = Users[i];
      // Do something with user
  }
}
catch(ArrayOutOfBoundException AOBE) {}

The replacement code will be better performance if the number of user is large.


When a database error occurs, should one return a null value, and error code or throw the exception? Ответ: В зависимости от того, какая ошибка. Например, если вы не можете найти пользователя, это не ошибка. Но если пароль неверен или соединение прервано, это ошибки, так как попытки обработать его обычным способом усложняют программу.

(1). Использование чрезмерного количества try-catch () отрицательно сказывается на производительности? Ответ: Насколько я помню, в соответствии с «Эффективной Java» он имеет очень-очень незначительный эффект (только не подходит для цикла) (сейчас у меня нет книги с собой)

(2). Лучше использовать определенные типы исключений? Ответ: Пользовательский вариант лучше, чтобы избежать решения неправильной проблемы.

Что, если я пропустил один из возможных X типов исключений, которые могли произойти? Честно говоря, я слышал и использую только 10% стандартных исключений Java за 2-3 года. Ответ: Точно так же, как если вы обрабатываете ошибку без исключения, вы тоже можете ее пропустить. Вы просто добавляете его, когда обнаруживаете это.

Да, кто-то сказал, что если вызывающий не знает, как поступать с ошибочными исключениями, он НЕ ДОЛЖЕН ИМЕТЬ ПРАВА на вызов метода throwing. Это правильно? Ответ: Нет, если я не знаю, что делать с каким-то исключением, перебросьте его заново

(3). Я прочитал статью Андерса Хейлсберга, в которой говорится, что проверенные исключения - это плохо. Означает ли это, что в некоторых случаях рекомендуется удобное проглатывание исключений? Ответ: Я думаю, он говорит о «Проверке исключения» как о функции компилятора, чтобы гарантировать, что какое-то исключение должно быть обработано. Идея исключения.

(4). Картинка стоит 1000 слов .. Думаю, здесь очень помогут несколько примеров. Ans: The code above.

I got the run now .... Sorry ... :-p (Be there in a minute, honey!!)

1
ответ дан 3 December 2019 в 21:22
поделиться

Пожалуйста, не возвращайте null в случае нефатальных ошибок.

1
ответ дан 3 December 2019 в 21:22
поделиться

Много хороших ответов, позвольте мне добавить пару моментов, которые не были упомянуты.

  1. Типы исключений должны быть настолько конкретными, насколько вызывающий может их различать. Под этим я подразумеваю, что если есть две возможные ошибки, A и B, и любой вызывающий, вероятно, сделает то же самое в обоих случаях, тогда создайте один класс исключения. Если вызывающий, вероятно, сделает две разные вещи, тогда создайте два класса исключений.

Для многих, вероятно, большинства исключений, которые я создаю, единственное, что программа может реально сделать, - это отобразить сообщение об ошибке и дать пользователю возможность изменить свои данные и попробовать еще раз. Большинство ошибок проверки - недопустимый формат даты, нецифры в числовом поле и т. Д. - попадают в эту категорию. Для них я создаю единственный тип исключения, который я обычно называю " getMessage, а затем ищет ключевые слова в сообщении, чтобы выяснить, в чем проблема. Это уродливо. Сделайте несколько исключений и сделайте это аккуратно.

  1. Есть три веские причины использовать исключения, а не другие способы обработки ошибок.

(a) Это позволяет избежать проблемы «магических» возвращаемых значений, например, ненулевой строки. реальный ответ, но null означает, что произошла ошибка. Или, что еще хуже, «NF» означает, что файл не найден, «NV» означает недопустимый формат, и все остальное - настоящий ответ. За исключением исключений, исключение - это исключение, а возвращаемое значение - это возвращаемое значение.

(b) Исключения аккуратно пропускают основную строку кода. Обычно, когда возникает ошибка, вы хотите пропустить целую кучу обработки, которая не имеет смысла без достоверных данных, и сразу перейти к отображению сообщения об ошибке и выходу или повторной попытке операции, или что там уместно. В старых плохих штампах мы писали «GOTO panic-abort». GOTO опасны по всем причинам, которые много обсуждались. Исключения устраняют то, что, возможно, было последней оставшейся веской причиной для использования GOTO.

(c) Возможно, дополнение к (b), вы можете справиться с проблемой на соответствующем уровне. Иногда, когда происходит ошибка, вы хотите повторить ту же самую функцию - например, ошибка ввода-вывода может представлять собой временный сбой связи. С другой стороны, вы можете оказаться на десяти уровнях подпрограмм, когда вы получите ошибку, которую невозможно обработать никаким способом, кроме взрыва всей программы и отображения сообщения «извините, армагедон произошел, все здесь мертвы». За исключением случаев, выбрать правильный уровень не только просто,

3
ответ дан 3 December 2019 в 21:22
поделиться

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

  1. Нет, чрезмерное использование try / catch не повлияет на производительность
  2. Использование наиболее специфичного типа исключения вы можете. Например, вам обычно не следует бросать Exception, если вы можете этого избежать. Выбрасывая определенный тип, вы даете понять пользователю, что может пойти не так. Однако вы можете перебросить его как нечто более общее, чтобы вызывающим абонентам, не связанным с конкретным исключением, не нужно было знать об этом (например, GUI не заботится, если это исключение IOException или исключение ArrayIndexOutOFBoundsException).
  3. Вы найдете людей, которым больше нравятся отмеченные исключения, и вы найдете людей, которым больше нравятся непроверенные исключения. В общем, я стараюсь использовать непроверенные исключения, потому что обычно с большинством проверенных исключений мало что можно сделать, и вы все равно можете обрабатывать непроверенные исключения, вам просто не нужно. Я часто обнаруживаю, что повторно генерирую проверенные исключения, так как я ничего не могу с ними поделать (другая стратегия - поймать проверенное исключение и повторно выбросить его как непроверенное, чтобы классам выше в цепочке не нужно было его ловить, если они не хотят

Обычно я люблю регистрировать исключения в том месте, где они были обнаружены - даже если я ничего не могу с этим поделать, это помогает диагностировать проблему. Если вы с ним не знакомы, изучите также метод Thread.setDefaultUncaughtExceptionHandler. Это позволяет обрабатывать исключения, которые никем не перехватываются, и что-то с ними делать.

7
ответ дан 3 December 2019 в 21:22
поделиться

One thing that we have done on our team is to have custom exceptions for our errors. We are using the Hibernate Validator framework, but you can do this with any framework, or stock exceptions.

For example, we have a ValidationException to handle validation errors. We have a ApplicationException to handle system errors.

You DO want to minimize your try-catch-ing. In our case, we will have the validator collect ALL the validations in "InvalidValue" objects, and then throw a single ValidationException with the invalid value information bundled into it. Then you can report to the user which fields were in error, etc.

In the case you mentioned of a database error - you may not want to send the stacktrace to the UI (logging it is a good idea). This is a case where you can catch the database exception, then throw your own ApplicationException to your GUI. Your GUI won't have to know how to deal with an infinite number of server errors, but can be set to deal with the more generalized ApplicationException - possibly reporting that there is a problem with the server, and indicating that the user should contact your customer support department to report the problem.

Lastly, sometimes you can't help but use a lot of try/catch blocks because of the external APIs you rely on. This is fine. As mentioned before, catch the external exception, and format it into one which makes more sense to YOUR application. Then throw the custom exception.

1
ответ дан 3 December 2019 в 21:22
поделиться
  1. Хотя у меня нет цифр, я не верю, что try-catch каким-либо образом влияет на производительность (не то, что я видел). Я думаю, что если вы не столкнетесь со многими исключениями, влияние на производительность будет практически нулевым. Но в любом случае лучше всего сначала позаботиться о правильной реализации кода, а во-вторых, о достижении хорошей производительности - гораздо проще сделать второе, когда будет выполнено первое.

  2. Я думаю, что класс исключения должен указывать на то, что на самом деле является исключением. Проблема с SQLExceptions в Java заключается в том, что они не дают вам информации о том, что на самом деле пошло не так. Spring использует набор более описательных исключений базы данных (исключения взаимоблокировок, исключения целостности данных и т. Д.). Таким образом вы можете определить, в чем проблема на самом деле.

  3. Проверенные исключения могут раздражать, но я не думаю, что они всегда плохие. Например, Spring использует непроверенные исключения для ошибок базы данных, но я все еще проверяю их и либо 1) обрабатываю их прямо здесь, если это возможно, или 2) помещаю в более общее исключение, которое показывает, что компонент вышел из строя.

  4. К сожалению, , Я не могу придумать никаких хороших конкретных исключений. Однако, как я уже сказал, правила исключений Spring мне показались полезными, но при этом не раздражающими, так что, возможно, вы могли бы посмотреть некоторые документы Spring. Классы базы данных Spring являются хорошим примером.

1
ответ дан 3 December 2019 в 21:22
поделиться
  • Чрезмерное использование try-catch () отрицательно сказывается на производительности?

Это похоже на микрооптимизацию, и, если это действительно влияет на производительность, вам придется иметь дело с много больших проблем с производительностью, прежде чем столкнуться с этим.

  • Лучше использовать определенные типы исключений? Что, если я пропустил один из возможных X типов исключений, которые могли произойти? Честно говоря, я слышал и использую только 10% стандартных исключений Java за 2-3 года. Да, кто-то сказал, что если вызывающий абонент не знает, как поступать с ошибочными исключениями, он НЕ ДОЛЖЕН ИМЕТЬ ПРАВА на вызов метода throwing. Это верно?

Я не уверен, что понял вопрос, но я бы сказал: «Если вы не знаете, что делать с исключением, повторно выбросьте его».

  • Я читал это статья Андерса Хейлсберга, говоря, что проверенные исключения - это плохо. Означает ли это, что в некоторых случаях рекомендуется удобное проглатывание исключений?

Ада нет. Это просто означает, что неконтролируемое исключение должно быть предпочтительным в некоторых случаях, особенно когда пользователь не знает, что делать с проверенным исключением (например, исключение SQL), или если нет возможности восстановления, ...

  • Изображение является стоит 1000 слов .. Думаю, здесь очень помогут несколько примеров.

Spring DataAccessException - очень хороший пример. См. Главу 10. Поддержка DAO .

SQL исключение), или, если восстановление невозможно, ...

  • Картинка стоит 1000 слов .. Думаю, здесь очень помогут несколько примеров.

Spring DataAccessException очень хороший пример. См. Главу 10. Поддержка DAO .

SQL исключение), или, если восстановление невозможно, ...

  • Картинка стоит 1000 слов .. Думаю, здесь очень помогут несколько примеров.

Spring DataAccessException очень хороший пример. См. Главу 10. Поддержка DAO .

1
ответ дан 3 December 2019 в 21:22
поделиться

se-radio подготовил эпизод подкаста на эту тему обработки ошибок, в котором объясняется некоторая философия использования исключений, которую можно переформулировать как «Где их поглотить»

. ] Главное, что я сохранил, - это то, что большинство функций должны позволять им всплывать, а большая часть деталей исключений должна попадать в файл журнала. Затем функции передают только глобальные сообщения о том, что что-то произошло.

В некотором смысле это приводит к своего рода иерархии исключений: по одному для каждого уровня кода.

Как я думаю, они сказали, что это не имеет смысла. объяснить пользователю, что такой кластер БД отказал из-за недоступности DNS или из-за переполнения диска. На этом уровне произошло что-то, что не позволило завершить транзакцию, это все, что пользователь должен знать.

Конечно,

1
ответ дан 3 December 2019 в 21:22
поделиться

Возвращаемое значение и выдача исключения

Принципиальное различие между исключением и возвращаемым значением состоит в том, что возвращаемое значение доставляется непосредственно вызывающему абоненту, а исключение доставляется в catch предложение в любом месте стека вызовов. Это позволяет повторно использовать один и тот же обработчик исключений для множества различных типов исключений. Я рекомендую вам отдавать предпочтение исключениям, а не кодам возврата, если и только если вам нужна эта функция.

Влияние на производительность.

Каждая инструкция отрицательно влияет на производительность, в том числе в блоках catch. Однако любой современный ЦП может генерировать и обрабатывать миллионы исключений в секунду, поэтому, если вы не выбросите тысячи из них, вы ничего не заметите.

Конкретные исключения

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

проверено

Бушуют споры о том, должны ли методы использовать проверенные или непроверенные исключения . Never just swallow an exception. Handle or rethrow it. It simplifies maintenance if you don't discard evidence about failures.

Example

An application I worked on recently receives commands over the network which it then executes. This usually involves further interaction with remote systems, which might fail for a host of reasons. The methods to carry out the command don't catch any exceptions, letting them bubble of the call stack to the central exception handler in the command listener, which does the following:

for (int retries = 0;; retries++) {
    try {
        commandService.execute(command);
        return;
    } catch (Exception e}
        Log.error(e);
        if (retries < 3) {
            continue;
        } else {
            saveForAnalysis(command, e);
            alertOperator();
            return;
        }
    }
}

We intentionally did not catch & rethrow exceptions in the processing logic, as we felt this would have added no value.

1
ответ дан 3 December 2019 в 21:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: