Concept of exceptions

Exceptions are some errors in a program, but not all errors are exceptions, and errors can sometimes be avoided.

For example, if your code is missing a semicolon, the result is java.lang.Error; If you use the System. The out. Println (11/0), then you because you do with zero divisor, throws Java. Lang. ArithmeticException abnormalities.

Exceptions can occur for many reasons, usually including the following categories:

  • The user entered illegal data.
  • The file to open does not exist.
  • The connection is down during network communication, or the JVM runs out of memory.

Some of these exceptions are caused by user error, some by programming errors, and some by physical errors. –

To understand how Java exception handling works, you need to understand three types of exceptions:

  • ** Checking exceptions: ** The most representative checking exceptions are exceptions caused by user errors or problems that the programmer could not have foreseen. For example, when trying to open a nonexistent file, an exception occurs that cannot simply be ignored at compile time.
  • Runtime exceptions: Runtime exceptions are exceptions that can be avoided by programmers. In contrast to checking exceptions, runtime exceptions can be ignored at compile time.
  • Errors: Errors are not exceptions, but problems outside the programmer’s control. Errors are generally ignored in code. For example, when a stack overflow occurs, an error occurs that is not detected at compile time.

Exceptions refer to unexpected conditions, such as file cannot be found, network connection failure, division by 0 operation, and invalid parameters. An exception is an event that occurs during program execution and interferes with the normal flow of instructions.

Java language did you consider these problems in the design, put forward the framework of exception handling scheme, all of the exception can be represented with an exception class, different types of anomalies correspond to different subclasses (now we call abnormalities including error concept), defines the specification of exception handling, after JDK1.4 version increased abnormal chain mechanism, This makes it easy to track exceptions.

A Java exception is an object that describes the exception that occurs in a code snippet. When an exception occurs, an object representing the exception is created and thrown in the method that causes the exception, and the method can choose to handle the exception itself or pass it.

Architecture of exceptions

Java treats exceptions as objects and defines a base class java.lang.throwable as a superclass for all exceptions.

Many Exception classes have been defined in the Java API, which fall into two broad categories, Error and Exception.

The Java exception hierarchy diagram is shown below:

You can see from the figure that all exception types are subclasses of the built-in Throwable class, so Throwable is at the top of the hierarchy of exception classes.

Next, Throwable splits into two different branches. One branch is Error, which indicates an Error that the program does not want to catch or that the program cannot handle. The other branch is Exception, which represents exceptions that a user program can catch or handle. The Exception class Exception is divided into RuntimeException and non-runtime Exception.

Java exceptions are classified into Unchecked exceptions and Checked exceptions.

The following details the differences and connections between these exceptions:

  • Error:ErrorClass objects are generated and thrown by the Java virtual machine, and most errors have nothing to do with what the code writer is doing. For example, the Java virtual machine runs incorrectly (Virtual MachineError), when the JVM no longer has the memory resources it needs to continue with the operationOutOfMemoryError. When these exceptions occur, the Java Virtual Machine (JVM) typically selects thread termination; It also happens when the virtual machine tries to execute an application, such as a class definition error (NoClassDefFoundError), link error (LinkageError). These errors are not detectable because they are outside the control and processing capabilities of the application, and most of them are not allowed to occur while the program is running. Even if an error does occur, a properly designed application should not, by nature, attempt to handle the exception it raises. In Java, errors are usually usedErrorSubclass description of.
  • ExceptionIn:ExceptionThere is an important subclass in the branchRuntimeExceptionThis type of exception is automatically defined for the program you writeArrayIndexOutOfBoundsException(array index out of bounds),NullPointerException(null pointer exception),ArithmeticException(arithmetic exception),MissingResourceException(Lost resources),ClassNotFoundException(can not find the class) and other exceptions, these exceptions are not checked exceptions, the program can choose to capture processing, can also not handle. These exceptions are generally caused by program logic errors, the program should avoid the occurrence of such exceptions as far as possible from the logical point of view; whileRuntimeExceptionExceptions other than exceptions are collectively referred to as non-runtime exceptions and are of typeExceptionClass and its subclasses are exceptions that must be handled syntactically. If not handled, the program will not compile. Such asIOException,SQLExceptionAnd user – definedExceptionException: Generally, you cannot customize the exception check.

Note the difference between Error and Exception: Error is usually a catastrophic and fatal Error that the program cannot control or handle. When these exceptions occur, the Java Virtual Machine (JVM) usually chooses to terminate the thread. Exceptions are usually handled by programs, and should be handled as much as possible in programs.

  • Check for anomalies: In the process of running the correct program, it is easy to appear, reasonable and acceptable abnormal conditions, to a certain extent, the occurrence of this anomaly can be predicted, and once the occurrence of this anomaly, must take some way to deal with.

♠ prompt

Exception classes and their subclasses except RuntimeException and their subclasses are check exceptions. When such exceptions may occur in a program, either a try-catch statement is used to catch them or a throws clause is used to throw them. Otherwise, the compilation fails.

  • Unchecked exceptions: Includes RuntimeException and its subclasses and Error.

♠ prompt

Unchecked exceptions are exceptions that the compiler does not require to be handled, and checked exceptions are exceptions that the compiler requires to be handled.

Java exception handling mechanism

Java exception handling is essentially throwing and catching exceptions.

  • An exception is thrownTo understand throwing exceptions, it is important to understand an exception condition, which is a problem that prevents the current method or scope from continuing to execute. Second, distinguish the exception case from the common problem, which is that there is enough information available in the current environment to always handle the error. In the case of exceptions, you can’t continue because you don’t have the necessary information to solve the problem in the current environment. All you can do is jump out of the current environment and refer the problem to the upper environment, which is what happens when an exception is thrown. After an exception is thrown, several things happen. First, it will be used as a normal Java objectnewCreate an exception object on the heap. Then, the current execution path (which can no longer be continued) is terminated and a reference to the exception object is ejected from the current environment. At this point, the exception handling mechanism takes over and starts looking for a proper place to continue executing the program. This proper place is the exception handler, or exception handler, whose job is to recover the program from its error state so that it can either run in a different way or continue running.

As a simple example, if we create a reference to the Student object Student, stu may not be initialized at the time of the call. You can create an object that represents the error message and throw it out of the current environment, propagating the error message to the larger environment.

if(stu == null){ 
        throw new NullPointerException();
}
Copy the code

This throws an exception, which will be executed or handled somewhere else, which will be described shortly, but the throw that appears in the code is a keyword, which I won’t go into too much for now, but more on later.

  • Catch exception: After the method throws an exception, the runtime system turns to finding the appropriate exception handler. A potential exception handler is a collection of methods that remain in turn in the call stack when an exception occurs. An exception handler is a proper exception handler when the type of exception it can handle matches the type of exception thrown by the method. The run-time system starts with the method where the exception occurred and goes back to the methods in the call stack until it finds a method with an appropriate exception handler and executes it. When the runtime system traverses the call stack without finding a suitable exception handler, the runtime system terminates. Also, it means the termination of the Java program.

prompt

Java technology requires different exception handling for runtime exceptions, errors, and check exceptions.

Due to the uncheckability of runtime exceptions and their subclasses, Java specifies that runtime exceptions are automatically thrown by the Java runtime system to make it more reasonable and easy to implement applications, allowing applications to ignore runtime exceptions.

Java allows a method to not make any throw declarations for errors that may occur during a method run when the running method does not want to catch them. For the most part, Error exceptions are conditions that should never be allowed to occur and exceptions that a reasonable application should not catch.

For all checked exceptions, Java dictates that a method must catch, or declare a method that throws out of the method. That is, when a method chooses not to catch a check exception, it must declare that it will throw an exception.

Java exception processing involves five keywords: try, catch, finally, throw, and throws. Here is a quick introduction to basic exception handling knowledge by understanding these five key words.

• 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 — Finally blocks are 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 method signatures to declare exceptions that the method may throw.

Basic syntax for exception handling

1. try-catch

try{
    //code that might generate exceptions    
}catch(Exception e){
    //the code of handling exception1
}catch(Exception e){
    //the code of handling exception2
}
Copy the code

To find exceptions and keep abreast of the concepts of Guarded Regions. It is a piece of code that may generate exceptions, followed by code that handles those exceptions.

Therefore, the try-catch described above is the monitoring area. A pair of curly braces after the keyword try wraps up a piece of code that may have an exception, namely the monitoring area. An exception occurs during the execution of a Java method, and an exception object is created. It is the responsibility of the Java runtime system to find a matching catch clause to catch the exception by throwing it out of the monitored area. If one catch statement matches, the exception handling code in that catch block is executed and no further attempts are made to match any other catch block.

The rule of matching is that if the exception object thrown belongs to the exception class of the catch clause, or is a subclass of that exception class, the generated exception object is considered to match the type of exception caught by the catch block.

Here’s an example of an arithmetic exception:

public class TestException { public static void main(String[] args) { int a = 1; int b = 0; If (b == 0) throw new ArithmeticException(); Println ("a/b is: "+ a/b); // Throw system.out.println ("a/b is:" + a/b); System.out.println("this will not be printed!" ); } catch (ArithmeticException e) {// Catch the ArithmeticException system.out.println (" the program is abnormal and the variable B cannot be 0!" ); } system.out.println (" Program completes normally." ); }}Copy the code

Running results:

D:\ Java > Java TestException Normal end of programCopy the code

To display an exception description, Throwable overloads the toString() method (defined by Object), so it will return a string containing the exception description. For example, rewrite the previous catch block as:

Catch (ArithmeticException e) {// Catch the ArithmeticException system.out.println (" the application is abnormal "+e); }Copy the code

Results:

D: \ Java > Java TestException abnormal Java program. Lang. ArithmeticException normal program ended.Copy the code

As mentioned earlier, arithmetic exceptions are runtime exceptions, so they don’t actually need to be thrown by the program. The runtime system throws them automatically.

public class TestException { public static void main(String[] args) { int a = 1; int b = 0; System.out.println("a/b is: "+ a/b); System.out.println("this will not be printed!" ); }}Copy the code

Results:

D:\java>java TestException

Exception in thread "main" java.lang.ArithmeticException: / by zero
    at TestException.main(TestException.java:7)
Copy the code

Use multiple catch statements: In many cases, a single piece of code can cause multiple exceptions. To handle this, we need to define two or more catch clauses. Each clause catches one type of exception. When an exception is raised, each catch clause is checked in turn.

Write multiple catch blocks

Order problem: small before big, that is, subclass before parent class

 

Java describes exception types through exception classes. For exception programs with more than one catch clause, try to put the catch clause that catches the low-level exception class first, and try to put the catch clause that catches the relatively high-level exception class later. Otherwise, the catch clause that catches the underlying exception class may be masked.

RuntimeException exception class various common abnormalities, including runtime ArithmeticException classes and ArrayIndexOutOfBoundsException class is a subclass of it. Therefore, the catch clause of the RuntimeException class should come last, otherwise it may mask subsequent specific exception handling or cause a compilation error.

Nested try statements: Try statements can be nested. That is, a try statement can be inside another try block. Each time a try statement is entered, the context of the exception is pushed onto the stack. If an internal try statement does not contain a catch handler for a particular exception, the stack pops up and the catch handler for the next try statement checks for a match. This process continues until a catch statement is matched, or until all nested try statements have been checked. If no catch statement matches, the Java runtime system handles the exception.

Such as:

class NestTry{ public static void main(String[] args){ try{ int a = args.length; int b = 42 / a; System.out.println("a = "+ a); try{ if(a == 1){ a = a/(a-a); } if(a == 2){ int c[] = {1}; c[42] =99; } }catch(ArrayIndexOutOfBoundsException e){ System.out.println("ArrayIndexOutOfBounds :"+e); } }catch(ArithmeticException e){ System.out.println("Divide by 0"+ e); }}}Copy the code

As shown in the program, the program nested a try block within another try block. The program works like this: When you execute the program with no command-line arguments, the outer try block produces an exception divided by 0. The program is executed with a command-line argument, and the nested try block produces an exception divided by 0. Since the internal catch block does not match the exception, it passes the exception to the external try block, where the exception is handled. If you execute the program with two command-line arguments, an array boundary exception will be generated by the internal try block.

Results:

D:\java>javac estTry.java

D:\java>>java NestTry

Divide by 0 java.lang.ArithmeticExceptio: / by zero

D:\java>java NestTry one

a = 1

Divide by 0java.lang.ArithmeticException: / by zero

D:\java>java NestTry one two

a = 2

ArrayIndexOutOfBounds :java.lang.ArrayIndexOutOfBoundsException: 42
Copy the code

Note: Nesting of try statements can occur stealthily when a method is called. For example, we can put a call to a method in a try block. Inside the method, there is another try statement. In this case, the try inside the method is still nested inside the outer try block calling the method. Now we’ll modify the above example by moving the nested try block inside the method nesttry() :

class NestTry{ static void nesttry(int a){ try{ if(a == 1){ a = a/(a-a); } if(a == 2){ int c[] = {1}; c[42] =99; } }catch(ArrayIndexOutOfBoundsException e){ System.out.println("ArrayIndexOutOfBounds :"+e); } } public static void main(String[] args){ try{ int a = args.length; int b = 42 / a; System.out.println("a = "+ a); nesttry(a); }catch(ArithmeticException e){ System.out.println("Divide by 0"+ e); }}}Copy the code

The resulting output is the same as the previous example:

D:\java>javac NestTry.java

D:\java>java NestTry

Divide by 0java.lang.ArithmeticException: / by zero

D:\java>java NestTry one

a = 1

Divide by 0java.lang.ArithmeticException: / by zero

D:\java>java NestTry one two

a = 2

ArrayIndexOutOfBounds :java.lang.ArrayIndexOutOfBoundsException: 42
Copy the code

2. throw

So far, we’ve only caught exceptions thrown by the Java runtime system. However, we can also throw an explicit exception with a throw statement. The syntax of Throw is as follows:

throw ThrowableInstance;
Copy the code

The ThrowableInstance must be an object of the Throwable class type or a Throwable subclass type. Simple data types, such as int, char, and non-throwable classes, such as String or Object, cannot be used as exceptions. There are two ways to get a Throwable object: using arguments in a catch clause or creating it using the new operator.

The program stops immediately after executing the throw statement; Anything after the throw is not executed, and the nearest try block is used to check if it contains a catch statement that matches the exception type. If a matching block is found, control is diverted to the statement; If none is found, the try block is then surrounded to check, and so on. If no matching catch block is found, the default exception handler interrupts the execution of the program and prints the stack trace.

Such as:

class TestThrow{ static void proc(){ try{ throw new NullPointerException("demo"); }catch(NullPointerException e){ System.out.println("Caught inside proc"); throw e; } } public static void main(String [] args){ try{ proc(); }catch(NullPointerException e){ System.out.println("Recaught: "+e); }}}Copy the code

Results:

D:\java>java TestThrow

Caught inside proc

Recaught: java.lang.NullPointerException: demo
Copy the code

The program handles the same error twice, first, the main() method sets up an exception relationship and then calls proc(). The proc() method sets up another exception-handling relationship and immediately throws a NullPointerException instance, which is caught again in main().

The program explains how to create Java’s standard exception object, paying particular attention to this line:

throw new NullPointerException("demo"); `Copy the code

Here new is used to construct a NullPointerException instance. All Java built-in runtime exceptions have two constructors: one with no arguments and one with a string argument. In the second form, the argument specifies the string that describes the exception. The string is displayed if the object is used as an argument to print() or println(). This can also be done by calling getMessage(), which is defined by the Throwable.

3. throws

If a method can cause an exception but not handle it, it must specify this behavior so that method callers can protect themselves from the exception. To do this, we can include a throws clause in the method declaration. A throws clause lists all types of exceptions that a method can throw. This is necessary for all exceptions of type other than Error or RuntimeException and their subclasses. All other types of exceptions that a method can throw must be declared in the THROWS clause, otherwise a compilation error will result.

The following is the general form of the method declaration for the throws clause:

public void info() throws Exception
{
   //body of method
}
Copy the code

Exceptions are all exceptions that the method may throw, or they can be a list of exceptions separated by commas.

Such as:

class TestThrows{ static void throw1(){ System.out.println("Inside throw1 . "); throw new IllegalAccessException("demo"); } public static void main(String[] args){ throw1(); }}Copy the code

There are two errors in the above example. Can you spot them?

There are two errors in this example. First, the throw1() method does not want to handle the resulting exception, so it must declare a throws clause to list the exceptions that may be thrown: IllegalAccess sexception. Second, the main() method must define a try/catch statement to catch the exception.

Examples are as follows:

class TestThrows{ static void throw1() throws IllegalAccessException { System.out.println("Inside throw1 . "); throw new IllegalAccessException("demo"); } public static void main(String[] args){ try { throw1(); }catch(IllegalAccessException e ){ System.out.println("Caught " + e); }}}Copy the code

Throws an exception rule:

  • If it is an unchecked anomaly (unchecked exception), i.e.,Error,RuntimeExceptionOr subclasses of them, then you don’t have to use themthrowsKeyword to declare the exception to be thrown, the compilation will still pass, but the system will throw it at run time.
  • You must declare any check exceptions that a method can throw (checked exception). That is, if a method is likely to have a detectable exception, eithertry-catchStatement capture, either withthrowsClause to throw it, otherwise a compilation error will result
  • Only if an exception is thrown must the method caller handle or rethrow it. When the method caller is unable to handle the exception, it should continue to throw rather than swallow it.
  • The calling method must follow the handling and declaration rules for any searchable exception. If you override a method, you cannot declare exceptions that are different from the override method. Any exception declared must be a class or subclass of the exception declared by the overriding method.

4. finally

When an exception occurs, the usual method execution will make a steeply non-linear turn, which may even cause the method to return prematurely. For example, if a method opens a file and closes it, then exits, you don’t want the code that closes the file to be bypassed by the exception handling mechanism. The finally keyword is designed to handle this kind of surprise.

A block of code created by finally is executed after a try/catch block has completed and before another try/catch appears. The finally block executes whether or not an exception is thrown. If an exception is thrown, finally is executed even if there is no catch clause match. Any time a method returns from a try/catch block to the calling program, after an uncaught exception or an explicit return statement, the finally clause is executed until the method returns. This is useful in closing file handles and freeing any other resources that were allocated at the start of the method.

The finally clause is optional and may be absent, but each try statement requires at least one catch or finally clause.

class TestFinally{ static void proc1(){ try{ System.out.println("inside proc1"); throw new RuntimeException("demo"); }finally{ System.out.println("proc1's finally"); } } static void proc2(){ try{ System.out.println("inside proc2"); return ; } finally{ System.out.println("proc2's finally"); } } static void proc3(){ try{ System.out.println("inside proc3"); }finally{ System.out.println("proc3's finally"); } } public static void main(String [] args){ try{ proc1(); }catch(Exception e){ System.out.println("Exception caught"); } proc2(); proc3(); }}Copy the code

In this example, proc1() throws an exception that interrupts the try, and its finally clause is executed on exit. The try statement of Proc2 is returned by a return statement, but the finally statement is executed before the return. In proc3(), the try statement executes without error, and the finally statement is executed.

Output result:

D:\java>java TestFinally inside proc1 proc1's finally Exception caught inside proc2 proc2's finally inside proc3 proc3's  finallyCopy the code

Note: If a finally block is used in conjunction with a try, the finally block is executed before the try ends.

Question Expansion (Interview questions):

1. Will the code in finally{} immediately following the try be executed and when, before or after the return?

Answer: It does, before the method returns to the caller.

* * note: ** It is bad to change the return value in finally, because if a finally block exists, 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 completes. Then, if the return value is changed in finally, The modified value is returned. Obviously, returning or modifying a return value in finally can cause a lot of trouble for a program. C# uses compiler errors to prevent programmers from doing the dirty work. Java can also raise the compiler’s syntax checking level to generate warnings or errors. It is highly recommended that this be set to a compilation error.

 

2, Java language how to handle exceptions, keywords: throws, throw, try, catch, finally respectively how to use?

A: Java takes an object-oriented approach to exception handling, classifying different exceptions and providing 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. The usual way to execute a program is to try. If the system throws an exception object, it can catch it by its type, or it can handle it by always executing a block of code (finally). Try is used to specify a piece of the program to prevent all exceptions; The catch clause, immediately after the try block, specifies the type of exception you want to catch; The throw statement is used to explicitly throw an exception; Throws throws. Throws is used to declare the various exceptions that a method may throw. Finally To ensure that a piece of code will be executed no matter what exception occurs; Try statements can be nested, and each time a try statement is encountered, the structure of the exception is placed on the exception stack until all try statements are complete. If the next level of try does not handle an exception, the exception stack executes out of the stack until either a try statement is encountered to handle the exception or the exception is finally thrown to the JVM.

3. What are the similarities and differences between runtime exceptions and checked exceptions?

A: An exception is an abnormal state that may occur during the running of a program. A runtime exception is an exception that may occur during the common operation of a VM. It is a common operation error that will not occur as long as the program is designed without any problems. Checked exceptions are related to the context in which the program is running. Even if the program is designed correctly, it can still be caused by problems in use. The Java compiler requires methods to declare to throw checked exceptions that can occur, but not run-time exceptions that are not caught. Exceptions, like inheritance, are often abused in object-oriented programming, and the following guidelines guide the use of exceptions in Effective Java:

  • Do not use exception handling for normal control flow (a well-designed API should not force its callers to use exceptions for normal control flow)
  • Use checked exceptions for recoverable cases and run time exceptions for programming errors
  • Avoid unnecessary use of checked exceptions (exceptions can be avoided by means of state detection)
  • Standard exceptions are preferred
  • Every exception thrown by a method should be documented
  • Maintain the atomicity of the anomaly
  • Do not ignore caught exceptions in a catch

4. List some of your common runtime exceptions.

A:

  • ArithmeticException
  • ClassCastException (class conversion exception)
  • IllegalArgumentException (invalid argument exception)
  • IndexOutOfBoundsException (subscript crossing the line)
  • NullPointerException
  • SecurityException

 

Abnormal chain

As the name implies, the exception chain is to chain the causes of the occurrence of exceptions one by one, that is, to pass the exception information from the bottom to the upper layer, so as to throw layer by layer. The Java API documentation provides a simple model:

try {   
    lowLevelOp();   
} catch (LowLevelException le) {   
    throw (HighLevelException) new HighLevelException().initCause(le);   
}

Copy the code

When the program catches an underlying exception, it chooses to continue throwing a new, higher-level exception to the method caller in the processing section. The cause of the exception is then passed layer by layer. This way, the exception at the higher level recursively calls the getCause() method to iterate over the cause of the exception at each level. This is how Java exception chains work. It is not a good idea to throw anomalies up layer by layer when they happen. What can the upper layer do to get these anomalies? Furthermore, throwing exceptions layer by layer consumes a lot of resources because a complete chain of exception information needs to be kept.

Custom exception

You can use Java’s built-in exception classes to describe most of the exceptions that occur during programming. In addition, users can customize exceptions. User-defined Exception classes, only need to inherit the Exception class.

Using custom exception classes in a program can be roughly divided into the following steps:

  • Create a custom exception class.
  • Pass through the methodthrowKeyword throws an exception object.
  • Can be used if the exception is handled in the method that currently throws ittry-catchStatement capture and processing; Otherwise, it passes at the declaration of the methodthrowsThe keyword indicates the exception to be thrown to the method caller to proceed.
  • Catch and handle the exception in the caller of the exception method.

Example User-defined exceptions:

class MyException extends Exception { private int detail; MyException(int a){ detail = a; } public String toString(){ return "MyException ["+ detail + "]"; } } public class TestMyException{ static void compute(int a) throws MyException{ System.out.println("Called compute(" + a + ")"); if(a > 10){ throw new MyException(a); } System.out.println("Normal exit!" ); } public static void main(String [] args){ try{ compute(1); compute(20); }catch(MyException me){ System.out.println("Caught " + me); }}}Copy the code

This example follows exactly the steps above.

D:\ Java > Java TestMyException Called compute(1) Normal exit! Called compute(20) Caught MyException [20]Copy the code

conclusion

 

The original address: www.cnblogs.com/Qian123/p/5…