1. Steps to implement custom exceptions
1. Determine the inheritance relationship
-
Checked Exception: Need to inherit
Exception
Class, suitable for scenarios that must be processed (such as file operation failure). -
Unchecked Exception:inherit
RuntimeException
Class, suitable for programming errors or unrecoverable problems (such as parameter verification failure). -
Error (Error): Generally not custom, because
Error
Indicates a serious system-level error (such as memory overflow).
2. Define the construction method
At least two construction methods must be included:
- Default constructor: Used for exception throwing without additional information.
- Constructor with message parameters: Pass specific error information for easy debugging.
public class MyCustomException extends Exception { public MyCustomException() { super(); } public MyCustomException(String message) { super(message); } // Optional: a constructor with a reason (Throwable) public MyCustomException(String message, Throwable cause) { super(message, cause); } }
3. Add custom logic (optional)
- Extensible methods, such as logging, encapsulating error codes, etc.:
public class BusinessException extends RuntimeException { private int errorCode; public BusinessException(int errorCode, String message) { super(message); = errorCode; } public int getErrorCode() { return errorCode; } }
4. Throw and capture
-
throw an exception: Used in blocks of code that need to trigger exceptions
throw
Statement. -
Capture processing:pass
try-catch
orthrows
Declare handling exceptions.
public void validateAge(int age) throws InvalidAgeException { if (age < 0) { throw new InvalidAgeException("Age cannot be negative"); } } // Callingtry { validateAge(-1); } catch (InvalidAgeException e) { ("error message:" + ()); }
2. Code examples and scenario analysis
Example 1: Basic custom exception
public class InsufficientBalanceException extends RuntimeException { public InsufficientBalanceException(String message) { super(message); } } // Use scenariopublic void withdraw(double amount) { if (amount > balance) { throw new InsufficientBalanceException("Insufficient balance, current balance:" + balance); } }
Example 2: Exception hierarchy with error codes
// Root exceptionpublic class BaseException extends RuntimeException { private String code; public BaseException(String code, String message) { super(message); = code; } public String getCode() { return code; } } // Subclass exceptionpublic class UserNotFoundException extends BaseException { public UserNotFoundException() { super("USER_404", "The user does not exist"); } }
3. Best practices and precautions
1. Naming Specifications
Class nameException
Ending (such asInvalidInputException
), enhance readability.
2. Design of abnormal information
- To avoid empty messages, a specific error description is required.
- Use parameterized constructors to support dynamic information:
throw new ValidationException("The value of parameter %s %d is out of range", "age", 150);
3. Exception hierarchy
- In large-scale projects, it is recommended to
RuntimeException
Derived root exception (e.g.BaseException
), and then expand the business subclass. - Avoid excessive inheritance and keep the levels flat.
4. Choice of tested and non-tested abnormalities
- Examined abnormality: It needs to be handled explicitly by calling, which is suitable for recoverable errors (such as network reconnection).
-
Unchecked exception: Suitable for programming errors (e.g.
NullPointerException
) to avoid code redundancy caused by forced processing.
5. Avoid abuse of custom exceptions
- Preferred use of built-in JDK exceptions (such as
IllegalArgumentException
、IllegalStateException
)。 - Customize only if standard exceptions cannot express business semantics.
4. Common misunderstandings
Misunderstanding 1: The exception information is too vague
- Error example:
throw new Exception("Error occurred")
。 - Improvement: clarify the cause of the error, such as
throw new FileParseException("Line 10 format is invalid")
。
Misunderstanding 2: Ignore exception chains
- Should be passed
cause
The constructor of the parameter retains the original exception:
try { // Code that may throw an IOException} catch (IOException e) { throw new DataLoadException("Loading data failed", e); // Pass the original exception}
Misunderstanding 3: Use exceptions for process control
- Exception handling costs are high, and abuse should be avoided through alternative solutions such as conditional judgment.
5. Summary
Custom exceptions significantly improve code maintainability by accurately expressing error types and encapsulating error information related to business logic. When implementing it, you need to pay attention to the inheritance system design, structural method integrity and the effectiveness of exception information, and at the same time, you should reasonably select the type of tested/non-checked exception based on project requirements. Following best practices can avoid common pitfalls and build robust exception handling mechanisms.
The above is personal experience. I hope you can give you a reference and I hope you can support me more.