Java interview summary summary, including Java key knowledge, as well as common open source framework, welcome to read. The article may have wrong place, because individual knowledge is limited, welcome everybody big guy to point out! The article continues to be updated at……
ID The title address 1 Design Mode Interview Questions (Most comprehensive summary of interview questions) Juejin. Cn/post / 684490… 2 Java Basics (most comprehensive interview questions) Juejin. Cn/post / 684490… 3 Java Set interview Questions (the most comprehensive interview questions) Juejin. Cn/post / 684490… 4 JavaIO, BIO, NIO, AIO, Netty Interview Questions (Most comprehensive summary of interview questions) Juejin. Cn/post / 684490… 5 Java Concurrent Programming Interview questions (most comprehensive interview questions) Juejin. Cn/post / 684490… 6 Java Exception Interview Questions (The most comprehensive interview Questions) Juejin. Cn/post / 684490… 7 Java Virtual Machine (JVM) Interview Questions Juejin. Cn/post / 684490… 8 Spring Interview Questions (the most comprehensive interview questions) Juejin. Cn/post / 684490… 9 Spring MVC Interview Questions (The most comprehensive interview Questions) Juejin. Cn/post / 684490… 10 Spring Boot Interview Questions (Most comprehensive summary of interview questions) Juejin. Cn/post / 684490… 11 Spring Cloud Interview Questions (The most comprehensive interview questions) Juejin. Cn/post / 684490… 12 Redis Interview Questions (most comprehensive summary of interview questions) Juejin. Cn/post / 684490… 13 MyBatis Interview Questions (most comprehensive interview questions) Juejin. Cn/post / 684490… 14 MySQL Interview Questions (most comprehensive interview questions) Juejin. Cn/post / 684490… 15 TCP, UDP, Socket, HTTP interview questions Juejin. Cn/post / 684490… 16 Nginx Interview Questions (The most comprehensive interview Questions) Juejin. Cn/post / 684490… 17 ElasticSearch interview questions 18 Kafka interview questions 19 RabbitMQ interview questions (most comprehensive summary of interview questions) Juejin. Cn/post / 684490… 20 Dubbo Interview Questions (the most comprehensive interview questions) Juejin. Cn/post / 684490… 21 ZooKeeper Interview Questions Juejin. Cn/post / 684490… 22 Netty Interview Questions (Most comprehensive summary of interview questions) 23 Tomcat Interview Questions (The most comprehensive interview questions) Juejin. Cn/post / 684490… 24 Linux Interview Questions (Most comprehensive Summary of interview questions) Juejin. Cn/post / 684490… 25 Internet Related interview Questions (the most comprehensive summary of interview questions) 26 Internet Security Questions (Summary of the most comprehensive interview questions)
Java exception schema and exception keywords
Introduction to Java Exceptions
- Java exceptions are a consistent mechanism provided by Java to identify and respond to errors. The Java exception mechanism separates exception-handling code from normal business code, making code more elegant and improving program robustness. When used effectively, exceptions clearly answer the questions what, Where, and why: the exception type answers the question “what” was thrown, the exception stack trace answers the question “where” was thrown, and the exception information answers the question “why” was thrown.
Java Exception Architecture
1. Throwable
-
Throwable is the superclass for all errors and exceptions in the Java language.
-
Throwable contains two subclasses: Error and Exception, which are usually used to indicate that an Exception has occurred.
-
Throwable contains a snapshot of the stack executed by its thread when it was created, and provides interfaces such as printStackTrace() to get information such as stack trace data.
2. Error
-
Definition: Error class and its subclasses. An unhandled error in the program indicates a serious error in running the application.
-
Characteristic: This type of error typically indicates a problem with the JVM while the code is running. There are usually Virtual MachineError (Virtual machine running error), NoClassDefFoundError (class definition error), etc. For example, OutOfMemoryError: OutOfMemoryError; StackOverflowError: StackOverflowError. When such an error occurs, the JVM terminates the thread.
-
These errors are unchecked exceptions, non-code errors. Therefore, the application should not handle such errors when they occur. By Java convention, we should not implement any new Error subclasses!
3. Exception
- Exceptions that can be caught and handled by the program itself. Exceptions fall into two categories: runtime and compile-time.
Runtime exception
-
Definition: The RuntimeException class and its subclasses represent exceptions that may occur during running by the JVM.
-
Features: The Java compiler does not check it. That is, when such an exception may occur in a program, it will still be compiled if “it is not thrown with a throw declaration” or “it is not caught with a try-catch statement”. Such as NullPointerException null Pointers, an abnormal ArrayIndexOutBoundException array subscript bounds, ClassCastException type conversion, an abnormal ArithmeticExecption arithmetic. This type of exception is not checked. It is usually caused by a program logic error. You can choose to catch and handle it or not handle it. Although the Java compiler does not check for runtime exceptions, we can declare a throw with throws, or we can catch it with try-catch. If a runtime exception is generated, you need to modify the code to avoid it. For example, if a divisor of zero occurs, you need to code to avoid it!
-
RuntimeException is automatically thrown and caught by the Java virtual machine (even if we didn’t write an exception capture statement at runtime!!). In most cases, the occurrence of such exceptions is that the code itself has a problem that should be solved logically and the code should be improved.
Compile time exception
-
Definition: Exception except for RuntimeException and its subclasses.
-
Features: The Java compiler checks it. If an exception occurs in a program, such as ClassNotFoundException (the specified class exception was not found) or IOException (the IO stream exception), the program cannot be compiled by either declaring a throw or try-catch. In a program, you usually do not customize the class exception, but use the exception classes provided by the system directly. The exception must be handled manually by adding a catch statement to the code.
4. Abnormal and non-abnormal detection
- All Exceptions in Java can be classified as checked exceptions and unchecked exceptions.
B. abnormal
- Exceptions that the compiler requires that must be handled. Correct program in the running process, often easy to appear, in line with the expected abnormal situation. Once such exceptions occur, they must be handled in some way. Exceptions except RuntimeException and its subclasses are checked exceptions. The compiler checks for this type of exception. That is, when the compiler detects a possible exception somewhere in the application, it prompts you to handle the exception — either by try-catch or throwing it with the method signature throws the throws keyword, or the compiler fails.
No abnormality under examination
- The compiler does not check and does not require exceptions that must be handled. That is to say, when such an exception occurs in the program, the compilation will pass even if we do not catch it with a try-catch or throw the exception with throws. This class includes runtime exceptions (RuntimeException and subclasses) and errors.
Java exception keyword
- Try – For listening. The code to be listened on (code that might throw an exception) is placed inside the try block, and when an exception occurs within the try block, the exception is thrown.
- Catch – Used to catch exceptions. Catch is used to catch exceptions that occur in a try block.
- Finally – The finally block is always executed. It is primarily used to reclaim physical resources (such as database connections, network connections, and disk files) that are opened in the try block. Only a finally block will return to execute a return or throw statement ina try or catch block. If a statement terminates a method such as a return or throw is used in the finally block, it will not jump back to execution.
- Throw – Used to throw an exception.
- Throws – used in a method signature to declare exceptions that the method may throw.
Java Exception Handling
-
Java uses object-oriented methods to handle exceptions. Once a method throws an Exception, the system automatically looks for an appropriate Exception Handler to handle the Exception according to the Exception object. It classifies different exceptions and provides a good interface. In Java, each exception is an object that is an instance of the Throwable class or a subclass of it. When an exception occurs in a method, an exception object is thrown. This object contains the exception information, and the method calling this object can catch the exception and handle it. Java exception handling is implemented with five keywords: try, Catch, throw, throw, and finally.
-
In Java application, exception handling mechanism is divided into declare exception, throw exception and catch exception.
Abnormal statement
- In general, you should catch exceptions that you know how to handle, and pass on those that you don’t. Passing exceptions You can declare exceptions that may be thrown using the throws keyword at the method signature.
Pay attention to
- Non-checking exceptions (Error, RuntimeException, or their subclasses) may not be declared to throw using the throws keyword.
- If a method has a compile-time exception, try-catch/ throws is required. Otherwise, a compilation error occurs.
An exception is thrown
-
You can throw an exception if you feel you can’t solve some exception problem that doesn’t need to be handled by the caller.
-
The throw keyword throws an exception of type Throwable inside a method. Any Java code can throw an exception through a throw statement.
Catch exceptions
- The program usually does not report an error before it is run, but after it is run, some unknown error may occur, but it does not want to throw directly to the next level, so it needs to try… The catch… , and then according to different exceptions to the corresponding processing.
How do I choose an exception type
- You can use the following figure to choose whether to catch, declare, or throw an exception
Common exception handling methods
Throw an exception directly
- In general, you should catch exceptions that you know how to handle, and pass on those that you don’t. Passing exceptions You can declare exceptions that may be thrown using the throws keyword at the method signature.
private static void readFile(String filePath) throws IOException {
File file = new File(filePath);
String result;
BufferedReader reader = new BufferedReader(new FileReader(file));
while((result = reader.readLine())! =null) { System.out.println(result); } reader.close(); }Copy the code
Encapsulate the exception and throw it
- Sometimes we throw an exception from a catch in order to change the type of exception. When multiple systems are integrated, when a subsystem fails, there may be multiple types of exceptions. You can use a unified exception type to expose the faults without exposing too many details about internal exceptions.
private static void readFile(String filePath) throws MyException {
try {
// code
} catch (IOException e) {
MyException ex = new MyException("read file failed."); ex.initCause(e); throw ex; }}Copy the code
Catch exceptions
- Multiple exception types can be caught in a try-catch block and handled differently for each type of exception
private static void readFile(String filePath) {
try {
// code
} catch (FileNotFoundException e) {
// handle FileNotFoundException
} catch (IOException e){
// handle IOException
}
}
Copy the code
- Can capture a variety of types that same catch exceptions, separated by |
private static void readFile(String filePath) {
try {
// code
} catch (FileNotFoundException | UnknownHostException e) {
// handle FileNotFoundException or UnknownHostException
} catch (IOException e){
// handle IOException
}
}
Copy the code
Custom exception
- Traditionally, defining an exception class should contain two constructors, a no-argument constructor and a constructor with detailed description information (Throwable’s toString method prints these details and is useful for debugging).
public class MyException extends Exception {
public MyException(){ }
public MyException(String msg){
super(msg);
}
// ...
}
Copy the code
try-catch-finally
- When an exception occurs ina method, the code after the exception will not be executed. If some local resources have been obtained before and need to be released, the code that releases local resources needs to be called both at the normal end of the method and in the catch statement, which is cumbersome. Finally statements can solve this problem.
private static void readFile(String filePath) throws MyException {
File file = new File(filePath);
String result;
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(file));
while((result = reader.readLine())! =null) { System.out.println(result); } } catch (IOException e) { System.out.println("readFile method catch block.");
MyException ex = new MyException("read file failed.");
ex.initCause(e);
throw ex;
} finally {
System.out.println("readFile method finally block.");
if(null ! = reader) { try { reader.close(); } catch (IOException e) { e.printStackTrace(); }}}}Copy the code
-
When this method is called, if an exception occurs while reading a file, the code goes into a catch block, followed by a finally block. If the file is read without an exception, the catch block is skipped and the finally block is directly entered. So the code in Fianlly executes whether or not an exception occurs in the code.
-
Will the code in finally execute if a catch block contains a return statement? Modify the catch clause in the above code as follows:
catch (IOException e) {
System.out.println("readFile method catch block.");
return;
}
Copy the code
- Call the readFile method to see if the finally clause executes when a return statement is called in the catch clause
readFile method catch block.
readFile method finally block.
Copy the code
- As you can see, the finally clause is executed even if a catch contains a return statement. If finally also contains a return statement, the return in finally overwrites the previous return.
try-with-resource
- In the example above, the close method in finally may also throw IOException, overwriting the original exception. JAVA 7 provides a more elegant way to automatically free resources from classes that implement the AutoCloseable interface.
private static void tryWithResourceTest(){
try (Scanner scanner = new Scanner(new FileInputStream("c:/abc"),"UTF-8")){
// code
} catch (IOException e){
// handle exception
}
}
Copy the code
- When the try block exits, the scanner. Close method is called automatically. Unlike placing the scanner. The suppressed exception will be added to the original exception by the addSusppressed method and if you want to get the list of suppressed exceptions you can call the getSuppressed method to get it.
Java exceptions often meet questions
1. What is the difference between Error and Exception?
-
The compiler does not detect these errors, and JAVA applications should not catch these errors. Once these errors occur, the application is usually terminated and cannot be recovered by the application itself.
-
Errors of the Exception class can be caught and handled in the application, and usually should be handled so that the application can continue to run normally.
2. What is the difference between run-time exceptions and normal exceptions (checked exceptions)?
-
Runtime exceptions include the RuntimeException class and its subclasses, which represent exceptions that can occur during runtime in the JVM. The Java compiler does not check for runtime exceptions.
-
Checked exceptions are exceptions in Exception other than RuntimeException and its subclasses. The Java compiler checks for checked exceptions.
-
The difference between a RuntimeException and a checked exception: Whether it is mandatory for the caller to handle the exception, if it is mandatory for the caller to handle the exception, then use the checked exception, otherwise select a RuntimeException. In general, if there are no special requirements, we recommend using RuntimeException.
3. How does the JVM handle exceptions?
-
If an exception occurs in a method, the method creates and passes to the JVM an exception object that contains the exception name, the exception description, and the state of the application at the time the exception occurs. The process of creating an exception object and passing it to the JVM is called throwing an exception. There may be a series of method calls that end up in the method that throws the exception. This ordered list of method calls is called the call stack.
-
The JVM follows the call stack to see if there is code that can handle exceptions, and if there is, it invokes exception handling code. When the JVM finds code that can handle an exception, it passes it the exception that occurred. If the JVM does not find a block of code that can handle the exception, the JVM passes the exception to the default exception handler (which is part of the JVM), which prints out the exception message and terminates the application.
4. What is the difference between throws and throws?
- Exception handling in Java includes not only catching and handling exceptions, but also declaring and throwing exceptions. You can declare the exception to be thrown by the method through the throws keyword, or throw an exception object inside the method.
Throws keyword and throw keyword in the use of the following differences:
- The throw keyword is used inside a method and can only be used to throw one exception. It can be used to throw an exception in a method or block of code.
- Throws a list of exceptions that the method may throw. A method identifies a list of exceptions that may be thrown with throws. The method calling the method must contain code that can handle exceptions; otherwise, the method signature must declare the corresponding exception with the throws keyword.
5. What is the difference between final, finally and Finalize?
- Final can modify classes, variables, and methods. A modifier class means that the class cannot be inherited, a modifier method means that the method cannot be overridden, and a modifier variable means that the variable is a constant and cannot be reassigned.
- Finally is usually used ina try-catch block. When handling an exception, the method finally is always executed, indicating that the block will be executed regardless of whether an exception occurs. It is used to store code that closes a resource.
- Finalize is a method that belongs to the Object class, which is the parent of all classes. Java allows you to use Finalize () to do the necessary cleanup before the garbage collector purifies objects from memory.
6. Difference between NoClassDefFoundError and ClassNotFoundException?
-
NoClassDefFoundError is an Error type exception that is raised by the JVM and should not be attempted to catch.
-
The cause of this exception is that when the JVM or ClassLoader tries to load a class, the definition of the class cannot be found in the memory. This action occurs during runtime, that is, the class exists at compile time, but cannot be found at runtime. It may be deleted after mutation or other reasons.
-
ClassNotFoundException is a checked exception that needs to be explicitly caught and processed using a try-catch, or declared with the throws keyword in the method signature. When using the Class. The class.forname, this loadClass. Or this findSystemClass dynamic Class is loaded into memory, didn’t find the Class through the incoming Class path parameters, throws the exception; Another possible reason for throwing this exception is that a class has been loaded into memory by one classloader and another loader tries to load it.
7. Which part of the try-catch-finally can be omitted?
- A: Catch can be omitted
why
-
More strictly, try is only good for runtime exceptions, and try+catch is good for run-time exceptions + normal exceptions. That is, if you just try a normal exception and don’t catch it, the compilation will fail because the compiler dictates that if you catch a normal exception, you must display the declaration with a catch for further processing. Run-time exceptions are not specified this way at compile time, so a catch can be omitted, and the compiler feels comfortable adding it.
-
In theory, any code that the compiler looks at is likely to have a problem, so even if you try everything, it’s just a layer on top of what it normally does at runtime. But once you add a try to a piece of code, you explicitly promise the compiler to catch exceptions that the code might throw instead of throwing them up. If it is a normal exception, the compiler requires that it must be caught with a catch for further processing. If there is a runtime exception, catch and discard and +finally sweep, or add a catch catch for further processing.
-
The addition of finally is a “sweep” processing that takes place whether or not an exception is caught.
8. In try-catch-finally, if a catch returns, will finally be executed?
-
A: It will be executed before return.
-
Note: It is bad to change the return value in finally, because if a finally block is present, the return statement in try does not return the caller immediately. Instead, it records the return value and returns it to the caller after the finally block is finished executing. Then, if the return value is modified in finally, the modified value is returned. Obviously, returning or modifying a return value in finally can cause a lot of trouble ina program. C# uses compiler errors to prevent programmers from doing the dirty work, and Java can raise the compiler’s syntax checking level to generate warnings or errors.
Code Example 1:
public static int getInt() {
int a = 10;
try {
System.out.println(a / 0);
a = 20;
} catch (ArithmeticException e) {
a = 30;
returna; / * *returnA at this point in the program, this is notreturnA butreturn30; The return path forms a * but it finds that finally is followed by finally, so it continues to execute finally. A =40 * returns to the previous path again and continuesreturnFinally {a = 40;} finally {a = 40; }return a;
}
Copy the code
- Result: 30
Code Example 2:
public static int getInt() {
int a = 10;
try {
System.out.println(a / 0);
a = 20;
} catch (ArithmeticException e) {
a = 30;
returna; } finally { a = 40; // If so, a new return path is formed, since only one path can be passedreturnReturn, so I'm just going to return 40returna; }}Copy the code
- Result: 40
9. Class ExampleA inherits Exception, and class ExampleB inherits ExampleA.
- There is the following code snippet:
try {
throw new ExampleB("b")} catch (ExampleA e) {system.out.println ("ExampleA"); } catch (Exception e) {system.out.println ("Exception");
}
Copy the code
-
What is the output of executing this code?
-
Answer: Output: ExampleA. (According to the Richter substitution principle, catching a catch block of ExampleA type exceptions can catch an exception of ExampleB type thrown in a try block.)
-
Interview question – State the result of running the following code. (This question comes from the book Java Programming Ideas)
class Annoyance extends Exception {
}
class Sneeze extends Annoyance {
}
class Human {
public static void main(String[] args)
throws Exception {
try {
try {
throw new Sneeze();
} catch ( Annoyance a ) {
System.out.println("Caught Annoyance");
throw a;
}
} catch ( Sneeze s ) {
System.out.println("Caught Sneeze");
return ;
} finally {
System.out.println("Hello World!"); }}}Copy the code
- The results of
Caught Annoyance
Caught Sneeze
Hello World!
Copy the code
10. What are the common RuntimeExceptions?
- ClassCastException(class conversion exception)
- IndexOutOfBoundsException (an array)
- NullPointerException
- ArrayStoreException(Data store exception, operating on arrays of different types)
- There is also a BufferOverflowException for IO operations
11. What are common Java exceptions
-
Java. Lang. IllegalAccessError: illegal access errors. This exception is thrown when an application attempts to access, modify, or call a class’s Field or method but violates the visibility declaration of the Field or method.
-
Java. Lang. InstantiationError: instantiation errors. This exception is thrown when an application attempts to construct an abstract class or interface using Java’s new operator.
-
Java. Lang. OutOfMemoryError: out of memory error. This error is thrown when the available memory is insufficient for the Java virtual machine to allocate an object.
-
Java. Lang. StackOverflowError: stack overflow error. This error is thrown when an application’s recursive calls are too deep and cause the stack to overflow or fall into an infinite loop.
-
Java. Lang. ClassCastException: class abnormal shape. Given that there are classes A and B (A is not A parent or subclass of B) and O is an instance of A, this exception is thrown when O is forced to be constructed as an instance of class B. This exception is often referred to as a cast exception.
-
Java. Lang. ClassNotFoundException: can’t find the abnormal class. This exception is thrown when an application tries to construct a class based on a string name and cannot find a class file with the name after traversing the CLASSPAH.
-
Java. Lang. ArithmeticException: arithmetic abnormal conditions. An integer divided by zero, etc.
-
Java. Lang. ArrayIndexOutOfBoundsException: array index cross-border anomalies. Thrown if the index value of an array is negative or greater than or equal to the array size.
-
Java. Lang. IndexOutOfBoundsException: index cross-border anomalies. This exception is thrown when the index value accessing a sequence is less than 0 or greater than or equal to the size of the sequence.
-
Java. Lang. InstantiationException: instantiate the exception. Throws this exception when an attempt is made to create an instance of a class that is an abstract class or interface through the newInstance() method.
-
Java. Lang. NoSuchFieldException: attributes, there is no exception. This exception is thrown when a nonexistent property of a class is accessed.
-
Java. Lang. NoSuchMethodException: there is no exception. This exception is thrown when a nonexistent method of a class is accessed. –
-
Java. Lang. NullPointerException: null pointer exception. Throws this exception when an application attempts to use NULL where an object is required. For example, calling instance methods of null objects, accessing properties of null objects, calculating the length of null objects, throwing null statements, and so on.
-
Java. Lang. A NumberFormatException: abnormal number format. This exception is thrown when an attempt is made to convert a String to the specified numeric type, but the String does not conform to the format required by the numeric type.
-
Java. Lang. StringIndexOutOfBoundsException: string index crossed the exception. This exception is thrown when a character in a string is accessed using an index value that is less than 0 or greater than or equal to the sequence size.
Java exception handling best practices
-
Handling exceptions in Java is not a simple matter. It’s not just beginners who are hard to understand; even experienced developers spend a lot of time thinking about how to handle exceptions, including which exceptions to handle, how to handle them, and so on. This is why most development teams have rules that govern exception handling. These specifications are often quite different from team to team.
-
This article presents several best practices for exception handling that are used by many teams.
1. Clean up resources in finally blocks or use try-with-resource statements
- When using a resource like InputStream that needs to be used and closed, a common mistake is to close the resource at the end of the try block.
public void doNotCloseResourceInTry() {
FileInputStream inputStream = null;
try {
File file = new File("./tmp.txt");
inputStream = new FileInputStream(file);
// use the inputStream to read a file
// do NOT dothis inputStream.close(); } catch (FileNotFoundException e) { log.error(e); } catch (IOException e) { log.error(e); }}Copy the code
- The problem is that this code only works if no exceptions are thrown. The code inside the try block executes normally, and the resource closes normally. However, there is a reason for using a try block. It is common to call one or more methods that might throw an exception. Also, you might throw an exception yourself, which means that the code might not execute to the end of the try block. As a result, you don’t close the resource.
So, you should either put the cleanup code in finally or use the try-with-resource feature.
1.1 Use finally code blocks
- Unlike the previous lines of try blocks, finally blocks are always executed. Either after the try block executes successfully or after you handle the exception in the catch block. Therefore, you can make sure that you clean up all open resources.
public void closeResourceInFinally() {
FileInputStream inputStream = null;
try {
File file = new File("./tmp.txt");
inputStream = new FileInputStream(file);
// use the inputStream to read a file
} catch (FileNotFoundException e) {
log.error(e);
} finally {
if(inputStream ! = null) { try { inputStream.close(); } catch (IOException e) { log.error(e); }}}}Copy the code
1.2 Java 7 try-with-resource syntax
- You can use this syntax if your resource implements the AutoCloseable interface. Most Java standard resources inherit this interface. When you open a resource in a try clause, the resource is automatically closed after the try block is executed or after an exception is handled.
public void automaticallyCloseResource() {
File file = new File("./tmp.txt");
try (FileInputStream inputStream = new FileInputStream(file);) {
// use the inputStream to reada file } catch (FileNotFoundException e) { log.error(e); } catch (IOException e) { log.error(e); }}Copy the code
2. Prioritize explicit exceptions
-
The more explicit the exception you throw, the better. Always remember that your colleague, or you in a few months, will be calling your method and handling the exception.
-
So you need to make sure you give them as much information as possible. This will make your API easier to understand. Callers of your methods can handle exceptions better and avoid extra checking.
-
So always try to find the class that best fits your exception event, for example, throwing a NumberFormatException instead of an IllegalArgumentException. Avoid throwing an ambiguous exception.
public void doNotDoThis() throws Exception {
...
}
public void doThis() throws NumberFormatException {
...
}
Copy the code
3. Document the exception
- It also needs to be documented when a method is declared to throw an exception. The goal is to give the caller as much information as possible so that exceptions can be better avoided or handled. Add an @throws declaration to Javadoc and describe the scenario in which an exception is thrown.
public void doSomething(String input) throws MyBusinessException {
...
}
Copy the code
Throw an exception using a descriptive message
-
When an exception is thrown, you need to describe the problem and related information as accurately as possible, so that it can be easily read in logs or monitoring tools to better locate specific error information and the severity of the error.
-
This is not meant to be a lengthy description of the error message, because the class name of Exception reflects the cause of the error, so only one or two sentences are needed.
-
If a particular exception is thrown, its class name probably already describes the error. So, you don’t need to provide a lot of additional information. A good example is NumberFormatException. When you supply a String in the wrong format, it will be thrown by the constructor of the java.lang.Long class.
try {
new Long("xyz");
} catch (NumberFormatException e) {
log.error(e);
}
Copy the code
5. Catch the most specific exceptions first
-
Most ides can help you implement this best practice. When you try to catch less specific exceptions first, they report unreachable blocks of code.
-
The problem is that only the first catch block that matches the exception is executed. Therefore, if you catch IllegalArgumentException first, you will never reach the catch block that should handle the more specific NumberFormatException, because it is a subclass of IllegalArgumentException.
-
Always catch the most specific exception class first, and add the less specific catch block to the end of the list.
-
You can see an example of such a try-catch statement in the code snippet below. The first catch block handles all NumberFormatExceptions, and the second handles all illegalArgumentExceptions that are not NumberFormatExceptions.
public void catchMostSpecificExceptionFirst() {
try {
doSomething("A message");
} catch (NumberFormatException e) {
log.error(e);
} catch (IllegalArgumentException e) {
log.error(e)
}
}
Copy the code
6. Do not capture Throwable classes
-
Throwable is the superclass for all exceptions and errors. You can use it in the catch clause, but you should never do so!
-
If you use Throwable in a catch clause, it will catch not only all exceptions, but also all errors. The JVM throws an error indicating a serious problem that should not be handled by the application. Typical examples are OutOfMemoryError or StackOverflowError. Both are caused by circumstances outside the control of the application and cannot be handled.
-
Therefore, it is best not to capture Throwable unless you are sure that you are in a special situation to handle errors.
public void doNotCatchThrowable() {
try {
// do something
} catch (Throwable t) {
// don't do this! }}Copy the code
7. Don’t ignore exceptions
- Many times, developers are confident that they will not throw an exception, so they write a catch block, but do nothing about it or log it.
public void doNotIgnoreExceptions() {
try {
// do something
} catch (NumberFormatException e) {
// this will never happen
}
}
Copy the code
-
But the reality is that often unexpected exceptions occur, or it is not certain that the code will change in the future (removing the code that prevents the exception from being thrown), and because the exception is caught, there is not enough error information to locate the problem.
-
It is reasonable to at least record the exception.
public void logAnException() {
try {
// do something
} catch (NumberFormatException e) {
log.error("This should never happen: "+ e); }}Copy the code
8. Do not log and throw exceptions
- This is probably the most overlooked best practice in this article. You can find a lot of code and even class libraries that have logic to catch exceptions, log them, and throw them again. As follows:
try {
new Long("xyz");
} catch (NumberFormatException e) {
log.error(e);
throw e;
}
Copy the code
- The logic seems reasonable. But this often outputs multiple logs for the same exception. As follows:
17:44:28, 945 ERROR TestExceptionHandling: 65 - Java. Lang. A NumberFormatException: For input string:"xyz"
Exception in thread "main" java.lang.NumberFormatException: For input string: "xyz"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Long.parseLong(Long.java:589)
at java.lang.Long.(Long.java:965)
at com.stackify.example.TestExceptionHandling.logAndThrowException(TestExceptionHandling.java:63)
at com.stackify.example.TestExceptionHandling.main(TestExceptionHandling.java:58)
Copy the code
- As shown above, no more useful information is appended to the later logs. If you want to provide more useful information, you can wrap the exception as a custom exception.
public void wrapException(String input) throws MyBusinessException {
try {
// do something
} catch (NumberFormatException e) {
throw new MyBusinessException("A message that describes the error.", e); }}Copy the code
- Therefore, catch exceptions only when you want to handle them, otherwise you simply declare them in the method signature for the caller to handle.
9. Do not discard the original exception when wrapping exceptions
- It is a common practice to catch standard exceptions and wrap them as custom exceptions. This allows you to add more specific exception information and to do specific exception handling. As you do this, be sure to set the original exception as the cause (note: Refer to the original exception E in NumberFormatException e below). The Exception class provides a special constructor method that takes a Throwable as an argument. Otherwise, you will lose the stack trace and messages for the original exception, which will make it difficult to analyze the exception events that caused the exception.
public void wrapException(String input) throws MyBusinessException {
try {
// do something
} catch (NumberFormatException e) {
throw new MyBusinessException("A message that describes the error.", e); }}Copy the code
10. Do not use the flow of exception control programs
- You should never use exceptions to control the execution flow of your application. For example, using exception handling when you should be using if statements for condition determination is a bad habit and can seriously affect application performance.
11. Use standard exceptions
- Do not define your own exceptions if you can solve the problem by using built-in exceptions. The Java API provides hundreds of different types of exceptions for different situations. In development, use the exceptions provided by the Java API as much as possible. If the standard exceptions do not meet your requirements, then create your own custom exceptions. Use standard exceptions whenever possible to help new developers understand the project code.
12. Exceptions affect performance
-
The performance cost of exception handling is very high, and every Java programmer should keep this in mind when developing. Creating an exception is slow, throwing an exception takes another 1 to 5ms, and when an exception is passed across multiple levels of the application, it can drag down the performance of the entire application.
- Use exceptions only in exceptional cases;
- Use exceptions in recoverable exception cases;
-
While using exceptions is good for Java development, it’s best not to capture too many call stacks in your application, because in many cases you don’t need to print the call stack to know what went wrong. Therefore, exception messages should provide just the right amount of information.
13. To summarize
-
To sum up, there are many different situations to consider when you throw or catch exceptions, and most of them are to improve the readability of your code or the usability of your API.
-
Exceptions are not only an error control mechanism, but also a communication medium. Therefore, in order to work well with colleagues, a team must develop best practices and rules so that team members can understand these common concepts and use them in their work.
Exception Handling – Alibaba Java Development Manual
-
“Mandatory” defined in the Java class library may avoid RuntimeException abnormalities by way of checking their shouldn’t catch ways to deal with, such as: NullPointerException, IndexOutOfBoundsException and so on. Note: Exceptions that do not pass the pre-check are exceptions, such as parsing strings of numbers that may have a wrong number format and have to be handled by a Catch NumberFormatException. If (obj! = null) {… } try {obj. Method (); } Catch (NullPointerException e) {… }
-
[Mandatory] Exceptions should not be used for process control or condition control. Note: The original intention of exception design is to solve all kinds of unexpected situations in program operation, and the efficiency of exception processing is much lower than the condition judgment method.
-
Make a distinction between stable code and unstable code when catching. Stable code is code that will not fail no matter what. For the catch of unstable code, distinguish the exception type as far as possible, and then do the corresponding exception processing. Note: A try-catch of large chunks of code prevents the program from responding correctly to different exceptions, and prevents it from locating problems. This is irresponsible. Example: In a user registration scenario, if a user enters illegal characters, a user name already exists, or a password is too simple, the system classifies the user and prompts the user.
-
Catch an exception to handle it. Do not throw it away without handling it. If you do not want to handle it, throw the exception to its caller. The outermost business consumer must handle the exception and turn it into something that the user can understand.
-
[Mandatory] If you need to roll back a transaction after a catch exception occurs, manually roll back the transaction.
-
【 Mandatory 】 The finally block must be used to close resource objects and stream objects, and try-catch exceptions must also be performed. Note: If JDK7 or higher, try-with-resources can be used.
-
Do not use a return ina finally block. If a return statement exists in the finally block, the return point in the try block will be discarded. Example:
private int x = 0;
public int checkReturn(a) {
try {
// x equals 1, not returned here
return ++x;
} finally {
// The result is 2
return++x; }}Copy the code
-
[Mandatory] Catch and throw must match exactly, or catch must be the parent of throw. Explanation: If the opposite party is expected to throw hydrangea ball, actually received shot put, there will be an accident.
-
The Throwable class must be used to intercept exceptions when calling RPC, binary packages, or methods related to dynamically generated classes. Call a method by reflection mechanism. If no method is found, throw NoSuchMethodException. When does a NosuchMethod ror get raised? In case of a class conflict, the mediation mechanism may cause the method signature of a class to be mismatched by the introduction of an unexpected version, or change the corresponding method signature when a bytecode modification framework (such as ASM) dynamically creates or modifiers a class. In these cases, NoSuchMethodError is raised at runtime, even if the code is correct at compile time.
-
The return value of a method can be null. It is not mandatory to return an empty collection, or an empty object, etc. Comments must be added to fully explain when null is returned. Note: This manual makes it clear that preventing NPE is the caller’s responsibility. Even if the called method returns an empty collection or an empty object, it is not easy for the caller to take into account null returns for remote call failures, serialization failures, runtime exceptions, and so on.
-
NPE prevention is a basic training for programmers. Pay attention to the following scenarios: 1) If the return type is basic data type, an NPE may be generated when an object of the data type is automatically unpacked. Counter example: public int f() {return Integer object}. If the value is null, the NPE is automatically unboxed. 2) The database query result may be null. 3) Even if the set is isNotEmpty, the fetched data element may be null. 4) When a remote call returns an object, null pointer judgment is required to prevent NPE. 5) For data obtained in Session, it is recommended to conduct NPE check to avoid null Pointers. 6) Cascade call obj.geta ().getb ().getc (); A series of calls, easy to generate NPE. Example: Use JDK8’s Optional class to prevent NPE problems.
-
Discard new RuntimeException() and throw exceptions or Throwable. Use custom exceptions with business significance. Custom exceptions defined in the industry are recommended, for example, DAOException/ServiceException.
-
Error codes must be used for external HTTP/API open interfaces. In-app recommendation exceptions are thrown; The Result method is preferred for inter-application RPC calls, encapsulating isSuccess() method, error code, and error brief message. Note: There are reasons for using Result method when RPC method return method is used: 1) If the caller does not catch the exception return method, it will generate a runtime error. 2) If no stack information is added, only new custom exception is added and error message of its own understanding is added, it will not be too helpful for the caller to solve the problem. If stack information is added, performance loss in data serialization and transmission is also an issue in the case of frequent invocation errors.
-
Don’t Repeat Yourself, the DRY principle. Note: Copy and paste code at will, will inevitably lead to code duplication, in the future need to modify, need to modify all copies, easy to miss. If necessary, extract common methods, or abstract common classes, or even componentize. Example: If multiple public methods in a class require the same parameter verification operation, extract: private Boolean checkParam(DTO DTO) {… }