Мы уже обрабатываем пользовательские исключения Java в коде почти каждого нашего стандартного отраслевого приложения. Распространенный подход заключается в создании собственного класса исключений, который семантически расширяет базовый класс исключений.
1) Пользовательская обработка исключений Java — новый подход
1.1 Традиционная обработка исключений
Наш новый подход использует статические внутренние классы для обработки каждого нового сценария исключения.
Традиционно мы унаследовалиException
класс для созданияDBException
. Затем каждый раз, когда нам нужно генерировать исключение, связанное с базой данных, мы создаемDBException
Например, выбросьте его после добавления некоторой информации.
Теперь давайте рассмотрим следующее, что нам нужно броситьDBException
Сценарий:
- Ошибка выполнения SQL
- Не удалось найти ни одной строки данных
- Когда нам нужна только одна строка данных, но мы возвращаем несколько строк данных
- Ошибка неверного параметра
- другие ошибки
Проблема с описанным выше подходом заключается в том, что когда эти исключения обрабатываются в блоке catch или в коде приложения,DBException
Предоставлено недостаточно информации для индивидуального рассмотрения исключительных случаев использования, перечисленных выше.
1.2 Новая обработка исключений с использованием внутренних классов
Давайте создадим внутренний класс для каждого варианта использования и объединим их вDBException
Давайте решим вышеуказанные проблемы внутренне.
Сначала создайте рефератBaseException
быть родительским классом для всех классов исключений.
// BaseException.java
public abstract class BaseException extends Exception{
private String message;
public BaseException(String msg)
{
this.message = msg;
}
public String getMessage() {
return message;
}
}
Теперь создайте нашException
внутренний класс.
// DBExeption.java
public class DBExeption
{
public static class BadExecution extends BaseException
{
private static final long serialVersionUID = 3555714415375055302L;
public BadExecution(String msg) {
super(msg);
}
}
public static class NoData extends BaseException
{
private static final long serialVersionUID = 8777415230393628334L;
public NoData(String msg) {
super(msg);
}
}
public static class MoreData extends BaseException
{
private static final long serialVersionUID = -3987707665150073980L;
public MoreData(String msg) {
super(msg);
}
}
public static class InvalidParam extends BaseException
{
private static final long serialVersionUID = 4235225697094262603L;
public InvalidParam(String msg) {
super(msg);
}
}
}
Здесь мы создаем ряд внутренних классов для обработки каждого исключения. Вы можете расширить новый внутренний класс исключения в соответствии с реальной ситуацией.
1.3 Как использовать пользовательские исключения
Чтобы понять, что он делает, давайте теперь создадим исключение и сгенерируем его. Тогда мы увидим сообщения об ошибках в логах.
// TestExceptions.java
public class TestExceptions {
public static void main(String[] args)
{
try
{
throw new DBExeption.NoData("No row found for id : x");
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
Вывод программы:
Console
com.exception.DBExeption$NoData: No row found for id : x
at com.test.TestExceptions.main(TestExceptions.java:7)
Как видно из сообщения журнала в стеке исключений, информация, которую оно несет, является более конкретной. Там четко видно, в чем ошибка. В коде приложения вы также можете выполнить соответствующую обработку, проверив экземпляр пользовательского исключения.
2. Преимущества использования внутренних классов в качестве пользовательских классов исключений
- Самым существенным преимуществом является то, что даже если другие разработчики пишут какие-то трудночитаемые сообщения об ошибках, вы можете четко понять, в чем конкретно ошибка.
- Вы можете использовать разные экземпляры исключений для обработки разных сценариев исключений.
- Вам не нужно использовать одно исключение, чтобы охватить множество исключений.
- Было бы проще написать отрицательные юнит-тесты
- Журналы стали более информативными и читабельными