Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to understand Java exception

2025-03-14 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

This article mainly explains "how to understand Java anomalies". The content of the explanation is simple and clear, and it is easy to learn and understand. Please follow the editor's train of thought to study and learn "how to understand Java anomalies".

Why use exceptions?

First of all, we can make it clear that the exception handling mechanism can ensure the robustness of our program and improve the availability of the system. Although we don't particularly like to see it, we have to recognize its status and function.

When there is no exception mechanism, we deal with it like this: the return value of the function is used to determine whether an exception has occurred (this return value is usually agreed), and the program that calls the function is responsible for checking and analyzing the return value. Although you can solve the exception problem, there are several drawbacks to doing so:

1. It is easy to be confused. If the agreed return value of-11111 indicates an exception, what if the final calculation result of the program is really-1111?

2. The readability of the code is poor. Confusing exception handling code with program code will reduce the readability of the code.

3. the exception is analyzed by calling the function, which requires the programmer to have a deep understanding of the library function.

The exception handling mechanism provided in OO is a powerful way to provide code robustness. Using the exception mechanism, it can reduce the complexity of error handling code, if you do not use exceptions, then you must check for a specific error and handle it in many parts of the program.

If you use an exception, you don't have to check at the method call, because the exception mechanism ensures that the error can be caught, and you only need to handle the error in one place, in the so-called exception handler.

This approach not only saves code, but also separates the code that "outlines what to do during normal execution" from the code "what to do if something goes wrong". In short, the exception mechanism makes the reading, writing, and debugging of the code more organized than previous error handling methods.

Basic definition of exception

Exceptions are defined in "Think in java" as follows: an exception condition is a problem that prevents the current method or scope from continuing to execute. One thing must be clear here: the exception code is wrong to some extent. Although Java has an exception handling mechanism, we can't look at the exception from a "normal" point of view. The reason for the exception handling mechanism is to tell you that there may be or have been an error here, and something abnormal may occur in your program, which may lead to program failure!

So when will there be an anomaly? Only if the program does not work properly in your current environment, that is, the program can no longer solve the problem correctly, it will jump out of the current environment and throw an exception. After throwing an exception, it does a few things first.

First, it creates an exception object using new, then terminates the program at the location where the exception was generated, and pops a reference to the exception object from the current environment. The exception handling mechanism takes over the program and starts looking for an appropriate place to continue executing the program, which is the exception handler.

Generally speaking, the exception handling mechanism is that when an exception occurs in the program, it forces the program to stop running, record the exception information and feed it back to us, and it is up to us to determine whether to handle the exception or not.

Abnormal system

Throwable is the superclass of all errors and exceptions in the java language. It has two subclasses: Error and Exception.

Some common exceptions are built into the Java standard library, with Throwable as the top-level parent for these classes.

Throwable also derives the Eror class and the Exception class.

Error: instances of the Error class and its subclasses represent the error of JVM itself. Errors cannot be handled by programmers through code, and Error rarely occurs. Therefore, programmers should pay attention to the various exception classes under the branch where Exception is the parent class.

Exception: Exception and its subclasses represent various unexpected events sent while the program is running. It can be used by Java exception handling mechanism and is the core of exception handling.

In general, we classify exception classes into two categories according to the requirements of Javac for exception handling.

Unchecked exceptions (unckecked exception): Error and RuntimeException and their subclasses. Javac does not prompt and find such exceptions when compiling, and it is not required to handle these exceptions in the program. So if we want, we can write code to handle it (using try... Catch... Finally) can also be left unhandled.

For these exceptions, we should fix the code instead of handling them through the exception handler. Most of the reason for such an exception is that there is something wrong with the code. Such as divide by 0 error ArithmeticException, wrong cast error ClassCastException, array index out of bounds ArrayIndexOutOfBoundsException, using an empty object NullPointerException, and so on.

Check for exceptions (checked exception): except for Error and RuntimeException. Javac forces programmers to prepare for such exceptions (using try. Catch... Finally or throws). In the method, either use the try-catch statement to capture it and process it, or declare to throw it with the throws clause, otherwise the compilation will not pass.

Such exceptions are generally caused by the environment in which the program is running. Because the program may be run in a variety of unknown environments, and the programmer cannot interfere with how the user uses the program he writes, the programmer should always be prepared for such exceptions. Such as SQLException, IOException,ClassNotFoundException and so on.

What needs to be clear is that checking and non-checking are for javac, so it's easy to understand and distinguish.

Initial recognition of anomalies

Exceptions are thrown when a function is executed, and the function is called at a hierarchical level, forming the call stack, because as long as an exception occurs to a function, all of its caller will be affected by the exception. When these affected functions output with exception information, the exception tracking stack is formed.

The place where the exception first occurs is called the exception throwing point.

Public class exception {public static void main (String [] args) {System. Out. Println ("- Welcome to the command line division calculator -"); CMDCalculate ();} public static void CMDCalculate () {Scanner scan = new Scanner (System. In); int num1 = scan .nextInt (); int num2 = scan .nextInt (); int result = devide (num1, num2); System. Out. Println ("result:" + result); scan. Close ();} public static int devide (int num1, int num2) {return num1 / num2;} / /-Welcome to the command line division calculator-/ / 1 Exception in thread / Exception in thread "main" java.lang.ArithmeticException: / by zero// at com.javase. Abnormal. Exception. Excepde (exception. Java: 24) / / at com.javase. Abnormal. Exception .CMDCalculate (exception .java: 19) / / at com.javase. Abnormal. Exception .main (exception .java: 12) / /-Welcome to the Command Line Division Calculator-/ / r Band / Exception in thread "main" java.util.InputMismatchException// at java.util.Scanner.throwFor (Scanner.java:864) / / at java.util.Scanner.next (Scanner.java:1485) / / at java.util.Scanner.nextInt (Scanner.java:2117) / / at java.util Scanner.nextInt (Scanner.java:2076) / / at com.javase. Abnormal. Exception .CMDCalculate (exception .java: 17) / / at com.javase. Abnormal. Exception .main (exception .java: 12)

As can be seen from the above example, when a division 0 exception occurs in the devide function, the devide function will throw an ArithmeticException exception, so calling his CMDCalculate function cannot be completed normally, so it also sends an exception, while the caller--main of CMDCalculate also throws an exception because the CMDCalculate throws an exception, so it keeps going back to the bottom of the call stack.

This behavior is called exception bubbling, which is used to find the nearest exception handler in the current exception function or in the function's caller. Since no exception handling mechanism is used in this example, the exception is eventually thrown to JRE by the main function, causing the program to terminate.

The above code does not use the exception handling mechanism and can be compiled smoothly because both exceptions are unchecked exceptions. But the following example must use the exception handling mechanism, because the exception is to check the exception.

In the code, I chose to use throws to declare the exception and let the caller of the function handle the possible exception. But why only throws IOException? Because FileNotFoundException is a subclass of IOException, it is within the scope of processing.

Exceptions and errors

Let's look at an example

/ / errors, that is, error generally refers to errors / / exceptions that jvm cannot handle. It is a tool defined by Java to simplify the error handling process and locate errors. Public class errors and errors {Error error = new Error (); public static void main (String [] args) {throw new Error () } / / the following four exceptions or errors have different handling methods public void error1 () {/ / compile time requirements must be handled, because this exception is the top-level exception, including checking the exception, you must handle try {throw new Throwable ();} catch (Throwable throwable) {throwable.printStackTrace () }} / / Exception must also be processed. Otherwise, an error is reported, because the check exceptions are inherited from exception, so they need to be caught by default. Public void error2 () {try {throw new Exception ();} catch (Exception e) {e.printStackTrace ();} / error can not be processed and compiled without reporting an error, because the virtual machine cannot handle it at all, so there is nothing to do with public void error3 () {throw new Error () } / / runtimeexception is known to compile without error public void error4 () {throw new RuntimeException ();} / Exception in thread "main" java.lang.Error// at com.javase. Abnormal. Error .main (error .java: 11)} exception handling

When writing code to handle exceptions, there are two different ways to check for exceptions:

Use try... Catch... The finally statement block processes it.

Alternatively, use the throws declaration in the function signature and give it to the function caller caller to solve.

Let's look at a few specific examples, including error,exception and throwable

The above example is a run-time exception and there is no need to display the capture. The following example is required to check for exceptions, to show catch or throw.

The constructor of @ Testpublic void testException () throws IOException {/ / FileInputStream throws FileNotFoundException FileInputStream fileIn = new FileInputStream ("E:\\ a.txt"); the int word; / / read method throws IOException while ((word = fileIn.read ())! =-1) {System.out.print ((char) word);} / / close method throws IOException fileIn.close ();}

The general way to deal with try catch finally

Public class exception handling {@ Testpublic void main () {try {/ / try block puts the code that may have an exception. InputStream inputStream = new FileInputStream ("a.txt"); / / if the try is executed and no exception occurs, then go on to execute the code following the finally block and finally, if any. Int I = 1max 0; / / if an exception occurs, try to match the catch block. Throw new SQLException (); / / using 1.8jdk to catch multiple exceptions at the same time, runtimeexception can also catch. Only the virtual machine cannot handle it after capture, so capture is not recommended. } catch (SQLException | IOException | ArrayIndexOutOfBoundsException exception) {System.out.println (exception.getMessage ()); / / each catch block is used to catch and handle a specific exception, or a subclass of this exception type. Multiple exceptions can be declared in a catch in Java7. The parentheses after / / catch define the exception type and exception parameters. If the exception matches and is the first to match, the virtual machine uses this catch block to handle the exception. / / the exception parameters of this block can be used in the catch block to obtain information about the exception. Exception parameters are local variables in this catch block and cannot be accessed by other blocks. / / if the exception occurred in the current try block is not caught in all subsequent catch, then execute the finally first, and then match the exception handler in the external caller of the function. / / if no exception occurs in the try, all catch blocks will be ignored. } catch (Exception exception) {System.out.println (exception.getMessage ()); / /...} finally {/ / finally blocks are usually optional. / / whether the exception occurs or not, whether the exception match is handled or not, finally will execute. / / finally mainly does some cleaning work, such as closing the stream, closing the database connection, and so on. }

A try must be with at least one catch or finally

Try {int I = 1;} finally {/ / a try must have at least one catch block, otherwise there must be at least one finally block. But finally is not used to handle exceptions, and finally does not catch exceptions. }}

The code behind the method does not run when an exception occurs, even if the exception has been caught. Here is a strange example of using try catch finally again in catch

@ Testpublic void test () {try {throwE (); System.out.println ("I threw an exception earlier"); System.out.println ("I won't execute");} catch (StringIndexOutOfBoundsException e) {System.out.println (e.getCause ()) } catch (Exception ex) {/ / you can still use try catch finally try {throw new Exception ();} catch (Exception ee) {} finally {System.out.println ("the catch block I'm in is not executed and I won't execute it") The exception thrown in the method declaration must be handled by the calling method or continue to be thrown up, / / when thrown to jre, the Terminator public void throwE () {/ / Socket socket = new Socket ("127.0.0.1", 80) will not report an error because it cannot be handled; / / when an exception is thrown manually, the method calling the method needs to handle the exception, otherwise an error will occur. / / java.lang.StringIndexOutOfBoundsException// at com.javase. Abnormal. Exception handling. ThrowE (exception handling. Java: 75) / / at com.javase. Abnormal. Exception handling .test (exception handling .java: 62) throw new StringIndexOutOfBoundsException ();}

In fact, some languages can continue to run after encountering an exception.

In some programming languages, when an exception is handled, the control flow returns to the point where the exception is thrown and then executes. This strategy is called resumption model of exception handling (recovery exception handling mode).

Java, on the other hand, restores the execution flow to the catch block that handled the exception and then executes it. This strategy is called termination model of exception handling (terminating exception handling mode).

"irresponsible" throws

Throws is another way to handle exceptions, unlike try. Catch... Finally,throws simply declares exceptions that may occur in the function to the caller, but does not specifically handle it.

The reason for this exception handling may be that the method itself does not know how to handle such an exception, or that the caller handles it better, and the caller is responsible for the possible exception.

Public void foo () throws ExceptionType1, ExceptionType2, ExceptionTypeN {/ / foo can throw exceptions of ExceptionType1, ExceptionType2, ExceptionTypeN classes, or exception objects of their subclasses. } tangled finally

Finally block whether an exception occurs or not, as long as the corresponding try executes, it must also execute. There is only one way to prevent the finally block from executing: System.exit (). Therefore, finally blocks are usually used to do resource release operations: close files, close database connections, and so on.

A good programming habit is to open resources in try blocks and clean up and release them in finally blocks.

Points to pay attention to:

1. Finally blocks do not have the ability to handle exceptions. It can only be catch blocks that handle exceptions.

2. In the same try... Catch... In the finally block, if an exception is thrown in the try and there is a matching catch block, the catch block is executed first, followed by the finally block. If there is no catch block match, execute the finally first, and then go to the outside caller to find the appropriate catch block.

3. In the same try... Catch... In the finally block, an exception occurs in try, and an exception is thrown when the exception is handled in the matching catch block, then the subsequent finally will also execute: first execute the finally block, and then go to the peripheral caller to find the appropriate catch block.

Public class finally uses {public static void main (String [] args) {try {throw new IllegalAccessException ();} catch (IllegalAccessException e) {/ / throw new Throwable (); / / if an exception is thrown again at this time, finally cannot be executed and can only report an error. / / finally will execute / / at any time unless I display the call. At this point, finally will not execute System.exit (0);} finally {System.out.println);} throw: keyword also used by JRE

Throw exceptionObject

Programmers can also manually explicitly throw an exception through the throw statement. The throw statement must be followed by an exception object.

The throw statement must be written in a function, and the place where the throw statement is executed is an exception throwing point, which is no different from the exception throwing point automatically formed by JRE. = =

Public void save (User user) {if (user = = null) throw new IllegalArgumentException ("User object is empty"); / /. }

Most of the content that begins later is extracted from http://www.cnblogs.com/lulipro/p/7504267.html.

This article is very meticulous and admirable, and it is the most detailed article I have ever seen about it, which can be said to be standing on the shoulders of giants.

Exception call chain

Abnormal chaining

In some large, modular software development, once an exception occurs in a place, like the domino effect, it will lead to a series of exceptions. Suppose that module B needs to call the method of module A to complete its logic. If module A has an exception, then module B will not be able to complete and an exception will occur.

= but when B throws an exception, it will cover up the exception information of A, which will cause the source information of the exception to be lost. The chaining of exceptions can connect the exceptions of multiple modules, so that the exception information will not be lost. = =

Exception chaining: a new exception object is constructed with an exception object as a parameter. The new different object will contain information about the previous exception. This technique is mainly implemented by a function of the exception class with a Throwable parameter. This exception as a parameter, we call it the cause exception.

Looking at the source code of the Throwable class, you can see that there is a Throwable field cause, which holds the source exception parameters passed during construction. This design is the same as the node class design of a linked list, so it is natural to form a chain.

Public class Throwable implements Serializable {private Throwable cause= this; public Throwable (String message, Throwable cause) {fillInStackTrace (); detailMessage = message; this.cause = cause;} public Throwable (Throwable cause) {fillInStackTrace (); detailMessage = (cause==null? Null: cause.toString (); this.cause = cause;} / /.}

Let's take a look at a more real example of exception chain.

Public class anomaly chain {@ Test public void test () {C ();} public void A () throws Exception {try {int I = 1; I = I / 0 / / when I commented out this line of code and threw an error using the B method, the result was as follows / / April 27, 2018 10:12:30 afternoon org.junit.platform.launcher.core.ServiceLoaderTestEngineRegistry loadTestEngines// message: Discovered TestEngines with IDs: [junit-jupiter] / / java.lang.Error: B also made an error / / at com.javase. Abnormal. Exception chain. B (exception chain. Java: 33) / / at com.javase. Abnormal. Exception chain. C (exception chain. Java: 38) / / at com.javase. Abnormal. Test (exception chain. Java: 13) / / at sun.reflect.NativeMethodAccessorImpl.invoke0 (NativeMethod) / / Caused by: java.lang.Error// at com.javase. Abnormal. Exception chain .B (exception chain .java: 29)} catch (ArithmeticException e) {/ / here the lowest exception is repackaged and thrown through the constructor of the throwable class, and the information of method An is injected. Finally, when printing the stack information, you can see the exception of the caused by A method. / / if thrown directly, the stack information print result can only see the error message of the upper method, but can not see that it is actually A that made an error. / / so you need to wrap and throw throw new Exception ("A method calculation error", e);}} public void B () throws Exception,Error {try {/ / received An exception, A (); throw new Error ();} catch (Exception e) {throw e } catch (Error error) {throw new Error ("B also made a mistake", error);}} public void C () {try {B ();} catch (Exception | Error e) {e.printStackTrace () }} / / final result / / java.lang.Exception: a method calculation error / / at com.javase. Abnormal. Exception chain .A (exception chain .java: 18) / / at com.javase. Abnormal. Exception chain. B (exception chain. Java: 24) / / at com.javase. Abnormal. Exception chain. C (exception chain. Java: 31) / / at com.javase. Abnormal. Exception chain. Test (exception chain. Java: 11) / / omit / / Caused by: java.lang.ArithmeticException: / by zero// at com.javase. Abnormal. Exception chain .A (exception chain .java: 16) / /. 31 more} Custom exception

If you want to customize the exception class, you can extend the Exception class, so such custom exceptions belong to the check exception (checked exception). If you want to customize unchecked exceptions, extend from RuntimeException.

According to international practice, a custom exception should always contain the following constructor:

A no-parameter constructor A constructor with a String parameter that is passed to the constructor of the parent class. One takes a String parameter and a Throwable parameter, both of which are passed to the parent class constructor, a constructor with the Throwable parameter, and to the parent class constructor. The following is the complete source code of the IOException class, which you can learn from.

Public class IOException extends Exception {static final long serialVersionUID = 7818375828146090155L; public IOException () {super ();} public IOException (String message) {super (message);} public IOException (String message, Throwable cause) {super (message, cause);} public IOException (Throwable cause) {super (cause);}} exception precautions

Abnormal precautions

When a subclass overrides a function with a throws declaration of a parent class, the exception declared by its throws must be within the controllable range of the parent class exception-the exception handler used to handle the parent class's throws method must also apply to the subclass's throws method. This is to support polymorphism.

For example, if the parent class method throws has 2 exceptions, the subclass cannot throws 3 or more exceptions. For the parent class throws IOException, the subclass must be a subclass of throws IOException or IOException.

As for why? I think maybe the following example can illustrate.

Class Father {public void start () throws IOException {throw new IOException ()}} class Son extends Father {public void start () throws Exception {throw new SQLException ();}}

/ * * assume that the above code is allowed (essentially wrong) * /

Class Test {public static void main (String [] args) {Father [] objs = new Father [2]; objs [0] = new Father (); objs [1] = new Son (); for (Father obj:objs) {/ / because what the Son class throws is SQLException, which IOException cannot handle. / / so the try here. Catch cannot handle exceptions in Son. / / Polymorphism cannot be achieved. Try {obj.start ();} catch (IOException) {/ / process IOException}

The exception execution flow of Java is thread independent and has no influence between threads = =

Java programs can be multithreaded. Each thread is an independent execution flow and a separate function call stack. If the program has only one thread, an exception that is not handled by any code will cause the program to terminate. If it is multithreaded, an exception that is not handled by any code will only cause the thread in which the exception is located to end.

In other words, the exception in Java is thread-independent, and the thread's problem should be solved by the thread itself, not delegated to the outside, and will not directly affect the execution of other threads.

Let's look at an example

Exception of public class multithreading {@ Test public void test () {go ();} public void go () {ExecutorService executorService = Executors.newFixedThreadPool (3); for (int I = 0 I)

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report