Home > Java > javaTutorial > body text

An in-depth exploration of exception and error handling in java

伊谢尔伦
Release: 2016-11-26 13:27:02
Original
981 people have browsed it

The exception handling mechanism in Java is relatively mature. Our Java programs are full of exception possibilities. If these exceptions are not handled in advance, it will be impossible to debug the program crash in the future, and it will be difficult to find the location of the exception. This article will discuss how to handle exceptions and errors in Java, let’s take a look.

Exceptions and Errors:

Exceptions:

In Java, program errors are mainly syntax errors and semantic errors. Errors that occur when a program is compiled and run are collectively called exceptions, which are VM (Virtual Machine) ) is a way of notifying you. In this way, the VM lets you know that you (the developer) have made a mistake and now have an opportunity to correct it. Exception classes are used in Java to represent exceptions, and different exception classes represent different exceptions. But all exceptions in Java have a base class called Exception.

Error:

It refers to a serious problem that cannot be intercepted by a reasonable application. Most are anomalies. An error is a failure of the VM (although it can be any system-level service). Therefore, errors are difficult to handle, and ordinary developers (not you, of course) cannot handle these errors, such as memory overflow. Like exceptions, error classes are used to represent errors in Java, and different error classes represent different errors. But all errors in Java have a base class called Error.

To sum up, we can know that the most essential difference between exceptions and errors is that exceptions can be handled by developers, while errors are native to the system and generally cannot be handled and do not require our programmers to handle them.

1. An exception is an event that occurs during the execution of a program, which interrupts the running of normal instructions
2. Error, an action or instance that deviates from acceptable code behavior

Structural classification of exceptions:

1. Runtime exception (unchecked exception)
2. Compile time exception (checked exception)

Runtime exception is RuntimeException; the rest are all compilation exceptions

In Java, Exception and Error have something in common Parent class Throwable.

Error Exception

runtimeException several subclasses
1. java.lang.ArrayIndexOutOfBoundsException
array index out-of-bounds exception. Thrown when the index into the array is negative or greater than or equal to the array size.

2. java.lang.ArithmeticException
Arithmetic condition exception. For example: integer division by zero, etc.

3. java.lang.NullPointerException
Null pointer exception. This exception is thrown when the application attempts to use null where an object is required. For example: calling the instance method of the null object, accessing the
attribute of the null object, calculating the length of the null object, using the throw statement to throw null, etc.

4. java.lang.ClassNotFoundException
The class exception cannot be found. This exception is thrown when the application attempts to construct a class based on a class name in string form, but cannot find the class file with the corresponding name after traversing CLASSPAH.

Exception handling:

try{}catch{}

try{}catch{}finally{} The finally code block will be executed regardless of whether there is an exception or not
try{}finally{} can also be used in combination, but catch{ }finally{} is not possible

Note: In the inheritance relationship, the subclass overrides the method of the parent class, and the scope of exceptions thrown cannot be wider than the parent class

Use of exceptions

This part of the use of exceptions is mainly for demonstration Code is what we usually encounter in the process of writing code (of course only a small part), why don’t you throw some light on it!

Example 1. This example mainly demonstrates the execution flow of the code after an exception occurs by comparing two methods. .

public static void testException1() {
int[] ints = new int[] { 1, 2, 3, 4 };
System.out.println("异常出现前");
try {
System.out.println(ints[4]);
System.out.println("我还有幸执行到吗");// 发生异常以后,后面的代码不能被执行
} catch (IndexOutOfBoundsException e) {
System.out.println("数组越界错误");
}
System.out.println("异常出现后");
}
   
/*output:异常出现前数组越界错误常出现后*/
public static void testException2() {
int[] ints = new int[] { 1, 2, 3, 4 };
System.out.println("异常出现前");
System.out.println(ints[4]);
System.out.println("我还有幸执行到吗");// 发生异常以后,他后面的代码不能被执行
}
Copy after login

First of all, point out the shortcomings in the example. IndexOutofBoundsException is an unchecked exception, so there is no need to try...catch...to display the capture, but my purpose is to use different handling methods for the same exception to see what difference it makes. And the result (I can only use it here for a while). When an exception occurs, the first method just jumps out of the try block, but the code behind it will still be executed. But the second kind is different and jumps directly out of the method, which is more tough. From the first method, we see that try...catch... is a "transactional" guarantee. Its purpose is to ensure that the program is completed under abnormal circumstances. At the same time, it will also inform the programmer of the details of the error in the program. information (the details sometimes depend on the programmer's design).

Example 2. Rethrow exception

public class Rethrow {
public static void readFile(String file) throws FileNotFoundException {
try {
BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));
} catch (FileNotFoundException e) {
e.printStackTrace();
System.err.println("不知道如何处理该异常或者根本不想处理它,但是不做处理又不合适,这是重新抛出异常交给上一级处理");
//重新抛出异常
throw e;
}
}
public static void printFile(String file) {
try {
readFile(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
printFile("D:/file");
}
}
Copy after login

The intention of exception is good, let us try to repair the program, but in reality our chance of repair is very small, we often use it to record error information. If you are tired of constantly handling exceptions, rethrowing exceptions may be a good relief for you. Throw this exception unchanged to the upper level, to the person who calls this method, and let him think about it. From this point of view, java exceptions (of course referring to checked exceptions) have caused us a lot of trouble, although its starting point is good.

Example 3. Use of exception chain and exception loss

ExceptionA,ExceptionB,ExceptionC
public class ExceptionA extends Exception {
public ExceptionA(String str) {
super();
}
}
public class ExceptionB extends ExceptionA {
public ExceptionB(String str) {
super(str);
}
}
public class ExceptionC extends ExceptionA {
public ExceptionC(String str) {
super(str);
}
}
Copy after login

Exception loss situation:

public class NeverCaught {
static void f() throws ExceptionB{
throw new ExceptionB("exception b");
}
static void g() throws ExceptionC {
try {
f();
} catch (ExceptionB e) {
ExceptionC c = new ExceptionC("exception a");
throw c;
}
}
public static void main(String[] args) {
try {
g();
} catch (ExceptionC e) {
e.printStackTrace();
}
}
}
/*
exception.ExceptionC
at exception.NeverCaught.g(NeverCaught.java:12)
at exception.NeverCaught.main(NeverCaught.java:19)
*/
Copy after login

Why is only ExceptionC printed but not ExceptionB? You should analyze this yourself!

Above The situation is equivalent to missing an exception, which is very disadvantageous in our troubleshooting process. So what should we do when we encounter the above situation? This is where the exception chain comes in: save the exception information, and throw another exception without losing the original exception.

public class NeverCaught {
static void f() throws ExceptionB{
throw new ExceptionB("exception b");
}
static void g() throws ExceptionC {
try {
f();
} catch (ExceptionB e) {
ExceptionC c = new ExceptionC("exception a");
//异常连
c.initCause(e);
throw c;
}
}
public static void main(String[] args) {
try {
g();
} catch (ExceptionC e) {
e.printStackTrace();
}
}
}
/*
exception.ExceptionC
at exception.NeverCaught.g(NeverCaught.java:12)
at exception.NeverCaught.main(NeverCaught.java:21)
Caused by: exception.ExceptionB
at exception.NeverCaught.f(NeverCaught.java:5)
at exception.NeverCaught.g(NeverCaught.java:10)
... 1 more
*/
Copy after login

The characteristics of this exception chain are shared by all exceptions, because the initCause() method is inherited from Throwable.

Example 4. Cleanup work

Cleanup work is essential for us, because if there are some resource-consuming operations, such as IO, JDBC. If we do not close it correctly in time after use, the consequences will be serious, which means memory leaks. The occurrence of exceptions requires us to design a mechanism so that resources can be cleaned up correctly and in a timely manner no matter what the circumstances. This is finally.

public void readFile(String file) {
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(
new FileInputStream(file)));
// do some other work
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Copy after login

The example is very simple, it is an example of reading a file. Such examples are also very common in JDBC operations. (So, I think the timely and correct cleanup of resources is one of the basic qualities of a programmer.)

Try...finally structure is also a means to ensure that resources are closed correctly. If you don't know what exceptions will occur during code execution that will prevent resources from being cleaned up, then you can use try to wrap this "suspicious" code, and then clean up the resources in finally. Give an example:

public void readFile() {
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(
new FileInputStream("file")));
// do some other work
//close reader
reader.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
Copy after login

Let’s pay attention to the difference between this method and the previous method. The next person may have a better habit of closing the reader as early as possible. But it often backfires, because exceptions may occur at any time before reader.close(), and such a code structure cannot prevent the occurrence of any exceptions. Because the program will jump out where the exception occurs, the subsequent code cannot be executed (this should be proven by examples above). At this time we can use try...finally to transform:

public void readFile() {
BufferedReader reader = null;
try {
try {
reader = new BufferedReader(new InputStreamReader(
new FileInputStream("file")));
// do some other work
// close reader
} finally {
reader.close();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
Copy after login

Closing resources early is a good behavior, because the longer the time, the greater the possibility that you will forget to close it. In this way, the coordination of try...finally is guaranteed to be foolproof (don't find it troublesome, Java is so satisfactory).

Let’s talk about another situation, if I want to open a file or create a JDBC connection in the construction method, because we need to use this resource in other methods, we cannot close this resource early in the construction method. So are we at a loss? The answer is no. Take a look at the following example:

public class ResourceInConstructor {
BufferedReader reader = null;
public ResourceInConstructor() {
try {
reader = new BufferedReader(new InputStreamReader(new FileInputStream("")));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
public void readFile() {
try {
while(reader.readLine()!=null) {
//do some work
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void dispose() {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Copy after login

This part goes a little bit further, but exceptions are indeed something that seems easy to use but difficult to use. There are still many things in Java that need to be explored deeply.


Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!