Java exceptions are divided into two categories: Checked exception and Runtime exception. Checked exceptions are exceptions that can be processed during the compilation stage.
The difference and connection between Checked exception and Runtime exception
Common exception classes
List several common runtime exceptions:
List several non-runtime exceptions (Checked exceptions):
Error
Error generally refers to problems related to virtual machines, such as system crashes, virtual machine errors, dynamic link failures, etc. This error cannot be recovered or cannot be captured, which will cause application interruption. Usually applications cannot handle these errors, so the program should not try to use catch to catch the Error object. There is no need to throws Error object when defining a method.
Use of Checked exceptions
As mentioned earlier, Checked must be handled explicitly, otherwise the compilation error will be reported, such as declaring a file input stream:
FileInputStream fis = new FileInputStream("test.md");This code will be compiled with an error
Unhandled exception type FileNotFoundException
Therefore, it must be handled explicitly, and there are generally two ways to handle Checked exceptions:
If you know how to handle it, it is best to use try...catch...block processing:
//Checked exception must be handled explicitly try { FileInputStream fis = new FileInputStream("test.md");} catch (FileNotFoundException e) { e.printStackTrace(); System.out.println("File does not exist!");}If you don't know how to deal with it, then throw it in the method and handle it by the previous caller:
public static void main(String[] args) throws FileNotFoundException { //Checked exception must be handled explicitly //Exception is thrown in the main method and handed over to the JVM for processing. The JVM's method of handling exceptions is to print the trace stack information and terminate the program to run FileInputStream fis = new FileInputStream("test.md");} Use throw to throw exceptions by yourself
Sometimes, according to business needs, we will throw exceptions in the program by ourselves. For example, if the read file content is empty, we think this is an exception. At this time, we can use throw to actively throw the exception and catch it:
// Use throw to actively throw an exception try { FileInputStream fis = new FileInputStream("test.md"); if(fis.read() == 0) { throw new IOException("Empty File"); }} catch (IOException e) { e.printStackTrace();}If throw throws a runtime exception, the program can be caught with try...catch... or ignore it.
Exception chain processing
In real enterprise-level applications, we often do not expose the underlying exceptions to the upper-level applications, such as not exposing SQL exceptions to the user interface. First, for users, seeing SQL exceptions is not helpful to them, and second, for malicious users, it is not safe to expose the underlying exceptions.
So how to block the underlying exception? The usual practice is: the program first catches the original exception, and then throws a new business exception. The new business exception contains prompt information to the user. This way of handling becomes exception translation. The following shows how a program that creates a user blocks the underlying exception:
//Demonstrate the exception chain and create the user public void createSubscriber(int subId) throws BusinessException { try { //Create the user's logic... }catch(Exception e){ //Process and save the original exception... //Top a new business exception throw new BusinessException("User creation failed"); }}You can see that the program hides the original exception and only provides the necessary exception prompt information upwards, which can ensure that the underlying exception will not be extended to the presentation layer, which is completely in line with the encapsulation principle of the object.
This kind of catching one exception, throwing another exception, and saving the original exception information is a typical chain processing, which is called the responsibility chain pattern in the design pattern.
Several suggestions for using exceptions
We use exceptions to achieve several goals:
To address these goals, we should:
1. Don't overuse or rely on it: Exceptions are very convenient, but don't use exception handling for normal logic, such as
//Original code if(fileSize > 100){ Sysotem.out.println("The file is too large, please upload again"); continue;}//Change to use exception if(fileSize > 100){ throw new Exception("The file is too large, please upload again");}//Doing this is obviously irresponsible.