# Java 自定义异常 – 最佳实践

> 原文： [https://howtodoinjava.com/java/exception-handling/best-practices-for-for-exception-handling/](https://howtodoinjava.com/java/exception-handling/best-practices-for-for-exception-handling/)

我们已经在几乎所有行业标准应用程序的代码中使用了 **java 自定义异常**处理。 通常的方法是创建一些自定义的异常类，以扩展基本的[异常处理最佳实践](https://docs.oracle.com/javase/8/docs/api/java/lang/Exception.html "Exception class")，这可能会使您更有意义。

## 1）Java 自定义异常处理 - 新方法

#### 1.1 传统异常处理

我们的新方法针对每个新的异常情况使用[**静态内部类**](https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html)。

传统上，我们通过扩展`Exception`类来创建`DBException`类。 现在，每次遇到需要抛出与数据库相关的异常的情况时，我们通常会创建`DBException`的实例，以消息的形式放置一些信息并将其抛出。

现在，让我们考虑以下几种情况，我们发现需要抛出`DBException`：

1.  SQL 执行错误
2.  我们预计至少需要一行数据，就没有数据
3.  存在多行，我们希望只有一行
4.  无效的参数错误
5.  还有更多这样的情况

上述方法的问题在于，在应处理这些异常的`catch`块或应用程序代码中，`DBException`没有提供足够的信息来唯一地处理每个居留权列出的用例。

#### 1.2 内部类的新异常处理

让我们使用内部类解决上述问题，我们将为每个用例创建一个类，然后将其分组到`DBException`类中。

让我们从创建为`abstract`的`BaseException`类开始，它将是我们所有异常类的超类。

```java
// Make this class abstract so that developers are forced to create
// suitable exception types only
public abstract class BaseException extends Exception{
	//Each exception message will be held here
	private String message;

	public BaseException(String msg)
	{
		this.message = msg;
	}
	//Message can be retrieved using this accessor method
	public String getMessage() {
		return message;
	}
}

```

不是时候创建新的`Exception`内部类。

```java
public class DBExeption
{
	//SQL execution error
	public static class BadExecution extends BaseException
	{
		private static final long serialVersionUID = 3555714415375055302L;
		public BadExecution(String msg) {
			super(msg);
		}
	}

	//No data exist where we expect at least one row
	public static class NoData extends BaseException
	{
		private static final long serialVersionUID = 8777415230393628334L;
		public NoData(String msg) {
			super(msg);
		}
	}

	//Multiple rows exist where we expect only single row
	public static class MoreData extends BaseException
	{
		private static final long serialVersionUID = -3987707665150073980L;
		public MoreData(String msg) {
			super(msg);
		}
	}

	//Invalid parameters error
	public static class InvalidParam extends BaseException
	{
		private static final long serialVersionUID = 4235225697094262603L;
		public InvalidParam(String msg) {
			super(msg);
		}
	}
}

```

在这里，我们为开始时确定的每种可能的错误情况创建了一个内部类。 可能还有更多其他功能。 *仅取决于您确定和添加更多类。*

#### 1.3 如何使用自定义异常

现在，要了解它的用处，让我们创建一个异常并将其抛出。 然后，我们将在日志中看到错误消息。

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

```

程序输出：

```java
com.exception.DBExeption$NoData: No row found for id : x
at com.test.TestExceptions.main(TestExceptions.java:7)

```

如您所见，在异常栈跟踪中的日志消息，它已变得**更具信息性**。 它清楚地说明了什么是错误。 同样在应用程序代码中，您可以**检查自定义异常**的实例并进行相应的处理。

## 2\. 使用内部类作为自定义异常的优点

1.  最重要的好处是，如果您的开发人员编写了一些可疑的消息文本，那么您也可以清楚地观察到实际出了什么问题。
2.  您可以在处理不同异常情况的不同情况下使用实例比较。
3.  您无需针对大量特殊情况发送单个异常。
4.  对于知道期望确切的异常类的否定情况，它很容易编写单元测试用例。
5.  日志记录更加有意义和有用。

我希望有关 Java 自定义异常的帖子对您​​有所帮助。 如果您有任何建议，请给我留言。

学习愉快！