J2SE 1.4 in Assertion function introduction

xiaoxiao2021-03-06  66

The assertion function provides a mechanism for correcting the correctness check in the code. This check is usually used in the development and commissioning phase. It can be turned off after the software is complete. This allows the programmer to add debug check statements in the code, while it can also avoid the impact on software speed and memory consumption after software deployment. basically,

The Assertion function is a new error check mechanism in Java, but this feature can be turned off as needed.

Usually in C and C , the determining function statement is the resulting process without compiling the final execution code. Since there is no macro function in Java, it is not widely used in the previous Java version, in JDK1. This situation is changed by increasing the Assert keyword.

The most important feature of this new feature is that the disclaimer statement can be turned on or off at runtime, which means that the statement of these error check functions does not have to delete from the source code after the development process is completed.

Assertion syntax is very simple, but the correct use can help us write a robust code. In this article, we not only learn how to write Assertion statements, but also to discuss what should be used in what circumstances.

First, Assertion syntax basic knowledge

We can use the new Java keyword assert to write the concluding statement. A concise statement has the following two legal forms:

Assert Expression1; Assert Expression1: Expression2;

Expression1 is a Boolean expression that must be guaranteed to be true during program execution; Expression2 is optional, and it is optional, which is used to pass to the constructor of an exception AssertionError, so therefore The type of Expression2 must be the parameter type of legitimate AssertionError constructor. Here are a few examples of concluding statements:

Assert 0

The expression of the Assert keyword must be a Boolean type, otherwise it will be wrong when compiling.

The following is a complete example of using a concluding statement (see crude body speech):

Public class aclass {public void amethod (int value) {assert value> = 0; system.out.println ("ok");} public static void main (string [] args) {aclass foo = new aclass (); system .out.print ("aclass.amethod (1):"); foo.amethod (1); system.out.print ("aclass.amethod (-1):"); foo.amethod (-1); }

This program uses statement assert value> = 0; to determine if the parameters in the AMETHOD method are not less than 0, if it is incorporated, the ASSERTIONError is triggered.

To be compatible with J2SE 1.4, Javac and Java commands in JDK1.4 are closed by default, that is, assert is not allowed as keywords, which guarantees that if you have written programs If you use Assert as a variable name or method name, the program does not have to modify still run. However, it should be noted that these programs are unable to recompile using JAVAC of JDK1.4, and can only be compiled with JDK1.3 or previous versions. In order to compile the applet written in front, first use the compiler compliant with the J2SE 1.4, but also use several command line parameters to enable the compiler to enable the assertion feature. Use the following command to compile aclass.java:

Javac -Source 1.4 ACLASS.JAVA

If we use Java Aclass to run this program, it will find that the assertion statement is not executed. Like Javac, the Java command is closed by default, and the assertion statement is ignored. How to enable the assertion statement will be discussed in the next section.

Second, control the assertion function through the command line

The most important feature of the Assertion statement is that it can be turned off, and the power is turned off. Although this code is still existing in the program, the JVM will ignore its existence and not execute, this code is running. Will not be affected by the existence of the assertian statement, if there is a problem during the code execution, we can also enable the assertion statement to help us analyze the judgment. By default, this feature is off. (Tip: The command line parameters introduced in this section are for JDK1.4 provided by Sun. If you use other companies' JDK, you may not be exactly the same.) JDK1.4, the command line options of the Java command - EA ( -ENABLEASSERTIONS an abbreviations are enabled. The following two commands are equivalent:

Java -ea mypackage.myprogramjava -ENABLEASSERTIONMYPACKAGE.MYPROGRAM

Similarly, we close the assertion feature through -DA (-disableassertions abbreviation):

Java -da mypackage.myprogramjava -disableassertions mypackage.myprogram

The assertion feature can also be enabled and off for a specific package (Class) or class (Class). For class, use a complete class name; when the package is for the package, the package is tight with "...":

Java -ea: mypackage.myprogramjava -da: ... mypackage.myprogram

When using multiple-EA -DA parameters in a java command, the following parameter settings override the settings of the front parameters, such as we can enable all Assertion features by default, but turn this feature for a specific package:

Java -ea -da: ... mypackage.myprogram

For unnamed packets (in the current directory) belong to the default package, you can use the following command control:

Java -ea: ... mypackage.myprogramjava -da: ... mypackage.myprogram

For all system classes you come with JVM, you can use -ESA (-EnablesystemAssertions) and -dsa (-disablesystemassertions) and -dsa (-disablesystemassertions) to control the enable and off. All usage of the control assertion function parameters are listed in Table 1.1. Table 1 Command line parameters related to the java command and assertion function in jdk1.4

Command line parameters

Example

meaning

-Eajava -ea Enables All-DAJAVA -DAs Except for System Category All classes ASSERTION-EA: Java-EA: AssertionClass enables AssertionClass Class ASSERTIONCLASS Class ASSERTIONCLASS Class. Da: assertionclass off AssertionClass class Assertion-Ea: java -ea: pkg0 ... Enable pkg0 package Assertion-Da: java -da: pkg0 ... Close PKG0 package ASSERTION-ESAJAVA -ESA Enable the assertion-dsajava-dsa in the system class to turn off the ASSERTION in the system class

At this point, the small program ACLASS we have written in front can run with any of the following commands:

Java-Ea Aclassjava-EA: ACLASS ACLASSJAVA -EA: ... ACLASS

The results are as follows: aclass.amethod (1): okaclass.amethod (-1): java.lang.assertionerRORAT Aclass.amethod (aclass.java: 3) at aclass.main (aclass.java: 12) Exception in thread "Main "

Third, the inheritance relationship between the assert command line parameters

The enabling and closing of the assertion function can always be controlled to each class, and a command line can accommodate any number of -ea -da parameters. How do these parameters work together, basically follow the two principles: specific specific settings It is preferentially set in general settings, and the set setting is preferred over the previous settings. Let's look at the example below:

// base.javaPackage Tmp; Public class base {public void m1 (boolean test) {Assert test: "assertion failed: test is" test; system.out.println ("ok");}}

// derived.java//package tmp.sub; import tmp.base; public class deive extends base {public void m2 {Assert Test: "Assertion Failed: Test IS" TEST; System.Out.Println "OK");} public static void printAssertionError (AssertionError ae) {StackTraceElement [] stackTraceElements = ae.getStackTrace (); StackTraceElement stackTraceElement = stackTraceElements [0]; System.err.println ( "AssertionError"); System.err.println ("class =" stacktracelement.getclassname ()); system.err.println ("method =" stacktracelement.getMethodName ()); system.rr.println ("message =" ae.getMessage ());} Public static void main (string [] args) {try {derived derived = new derived (); system.out.print ("Derived.m1 (false):"); derived.m1 (false); system.out.print ("Derived.m2 (false):"); Derived.m2 (false);} catch (assertionerror ae) {printassertionError (AE);}}} Base class and Derived class have a method M1 and M2, because Derived is Base's subclasses, so it follows Under the method M1.

First, run the program after enabling all the assertion features:

Java -ea tmp.sub.derived

Derived.m1 (false): assertionerrorclass = tmp.basemethod = m1message = assertion failed: test is false

Then, let's turn off the Assertion feature of the Base class, run the program:

Java -ea -da: tmp.base tmp.sub.derived

DERIVED.M1 (FALSE): Okderived.m2 (false): assertionerrorclass = tmp.sub.derivedMethod = m2message = assertion failed: test is false

It can be seen that the derived.m1 (false) statement does not trigger an exception, apparent that this statement is controlled by the Assertion functionality of the Base class. If you continue research, you will find the following two statements.

Java-Da: Tmp.Base -ea: TMP ... TMP.SUB.DERIVEDJAVA -EA: TMP ... -DA: TMP.BASE TMP.SUB.DERIVED This shows that the two principles mentioned above works .

Fourth, control the assertion function in the program code

Enable and shutdown by Assertion can also be controlled inside the code. In general, it is not necessary, unless we are writing a Java program, or a program that controls the Java program.

Each Java class has an identifier that represents its Assertion feature enabled. When the program runs to the Assertion statement, the JVM checks the Assertion identifier where this line Assertion statement is located. If it is true, then this statement will be executed, otherwise this statement is ignored.

This assertion identifier can set the following method of ClassLoader:

Public void setclassassertionStatus (String ClassName, Boolean Enabled);

ClassName - a class that needs to be set assertion identifier

Enabled - assertion function is enabled or closed

This Assertion identifier can also be controlled with the entire package, and the other method of ClassLoader is set:

Public void setPackageAsSstatus (String packagename, boolean enabled);

ClassName - Package that needs to set the assertion identifier

Enabled - assertion function is enabled or closed

Note that this method also works on all subclats of package packagename.

ClassLoader has a way to set the default Assertion status of all classes loaded by this ClassLoader:

Public void setDefaultsrtionsTatus (Boolean enabled);

Finally, ClassLoader has a method to clear all previous settings:

Public void clearassertionstatus ();

The Class class also adds a method related to the assertion feature, using this method to know that a class's assertion function is to be enabled or off:

Public Boolean DesiredassertionsTatus ();

Note: To set the Assertion identifier by ClassLoader only affects the classes loaded after this ClassLoad, without changing the ASSERTION identifier status of the previously loaded class.

5. AssertionError introduction

The java.lang package adds the Assertinerror class, which is the direct subclass of Error, so the representative program has a serious error, which is usually not required to use the Catch statement to use the Catch statement. In addition to a default constructor without parameters, there are seven constructors with a single parameter, respectively:

Object Boolean Char Int Long Float

Double

The two grammar forms of the Assertion statement mentioned earlier are as follows:

Assert Expression1; Assert Expression1: Expression2;

In the first form, if an exception is thrown, the default constructor of AssertionError is called. For the second form, the seven single parameter constructor is called according to the type of Expression2 value.

Below we make a slight modification, see the use of the second ASSERTION expression:

Public class aclass2 {public void m1 (int value) {assert 0 <= value: "Value Must Be Non-Negative: Value =" Value; System.out.Println ("OK");} public static void printassertionError (Assertionerror) ae) {StackTraceElement [] stackTraceElements = ae.getStackTrace (); StackTraceElement stackTraceElement = stackTraceElements [0]; System.err.println ( "AssertionError"); System.err.println ( "class =" stackTraceElement.getClassName ()) System.err.Println ("Method =" stackTraceElement.getMethodName ()); system.err.println ("message =" ae.getMessage ());} public static void main (string [] args) {TRIN {Aclass2 foobar = new aclass2 (); system.out.print ("aclass2.m1 (1):"); foobar.m1 (1); system.out.print ("aclass2.m1 (-1):") FOOBAR.M1 (-1);} catch (assertionerror ae) {printassertionError (AE);}}} The results are as follows:

Aclass2.m1 (1): okaclass2.m1 (-1): assertionerrorclass = aclass2method = m1message = value must be non-negative: value = -1

From the above results, you can find that an Assertion statement: The subsequent parameters are passed to the STACKTRACE of the ASSERTIONERRACE.

Since AssertionError represents an error that should not appear normally, once there is an emergence, it should be thrown as soon as possible, the execution of the procedure will be noted to cause the program maintenance personnel. But sometimes we also need to capture AssertionError, perform some tasks, then resolve AssertionError. For example, our program has a console to monitor the operation of the entire system in the network. We need to get an exception information about AssertionError, transfer to the console via the network, then throw an AssertionError, abort the program, as an example 3 Do it:

Public void method () {assertionerror ae = null; try {int a = anotherMethod (); // ... assert i == 10; // ...} catch (assertionerror ae2) {ae = ae2; StackTraceElement STES [ ] = a.getStackTrace (); if (STES.LENGTH> 0) {StackTraceElement first = STES [0]; System.out.Println ("NOTE: Assertion Failure In" first.getFileName () "at line" First.getLinenumber ());} else {system.out.println ("NOTE: NO Info Available.");} throw ae;}} 6. Several guidelines for Assertion

For Assertion, it is important not to use, but when and where it is used. This section will introduce several guidelines, in Table 2, can help us make the correct judgment when deciding whether there should be a question like ASSERTION statement.

Table 2: Do you use the judgment principle of an assertion statement?

The situation that should be used

Will not use the situation

Used to ensure the correct internal data structure

The correct use of the command line parameters is not used to ensure the correct use of the private method parameter to ensure the correct use of the public (the public) method parameter is used to check the correctness of the status of the state to check whether the outside of the public method is used. Correctly used to check the status that should not appear is not to ensure that the correctness of the information that should be provided by the user is used to check the status that should not appear, even if you do not do not use the IF statement for use in any method Start check Related initial status Do not use the external control condition to check some states in a long cycle execution not to check the correctness of the compiler, operating system, hardware, unless you have it in the debugging process Reason, I believe they have errors

The Assertion statement is not a short written by an IF (Expression). Instead, it is an important means of ensuring robust code. It is important to distinguish when to use Assertion and use a general conditional expression. The following is the case where you need to pay attention to using the Assertion statement.

Don't use assertion to ensure the correct command line parameters

Use the programs for use the command line parameters to check the correctness of these parameters, but this should be implemented through normal conditions. Here is an example of an error using Assertion.

Public class application {static public void main (string args []) {// bad !! assert args.length == 3; int a = integer.parseint (args [0]); int b = integer.parseint (Args [ 1]); int c = integer.parseint (args [2]);}}

If your program must have three parameters, otherwise, the better way is to throw the appropriate RuntimeException:

Public class app {static public void main (string args []) {if (args.length! = 3) throw new runtimeException ("usage: ABC"); int a = integer.parseint (args [0]) INT b = INTEGER.PARSEINT (Args [1]); INT C = Integer.Parseint (args [2]);}} The role of Assertion statement is the consistency of the program instead of the consistency between users and programs Sex.

Use assertion to ensure the correctness of passing to private method parameters

The following private methods have two parameters, one is necessary, one is optional.

Private void method (object optional) {ask! = null: "Method (): Required = null;}

Typically, private methods are only called inside the class, and thus the programmer can control, we can expect its status to be correct and consistent. We can also assume that the call to it is correct, which naturally includes the correctness of the calling parameters, so you can use the assertion statement to ensure this accuracy.

This principle also applies to Protected and Package-Protected methods.

Do not use Assertion to ensure the correctness of the public method parameters

Below this public method has two parameters, Source and Sink represent heads and tails, respectively, and they are interconnected. Before disconnecting the connections, it must be ensured that there is already interconnected:

Public void disconnect (Source Source, Sink Sink) {// Bad !! Assert Source.isconnected (SINK): "Disconnect (): NOT Connected" Source "," SINK;

Since this method is public, the relationship between Source and Sink is what we cannot control. This kind of we cannot guarantee that the correct occasion is not suitable for using the assertion statement.

More importantly, the public method may be called many different programs, which must ensure that its interface features are identical in different call situations. Since the assertion statement is not guaranteed to be run, depending on whether the assertion function in the running environment is enabled, if the assertion function is not enabled, the PUBLIC method parameter cannot be guaranteed.

In this case, you should assume that the calling code is possible, throws an appropriate exception:

Public void disconnect (Source Source, Sink Sink) THROWS IOException {if (! Source.isconnected (SINK)) {throw new ioException ("disconnect (): not conne connect" source "," sink);}}

Don't use Assertion to ensure that the external use of public methods is correct.

The following PUBLIC class may be in two states, Open or Closed. Open an open Connection, close a closed Connection is incorrect. However, we should not use assertion feature to ensure that this error does not happen: public class connection = false; public void open () {// ... isopen = true;} public void close () {//// Bad !! Assert Isopen: "Cannot Close A Connection That IS Not open!"; // ...}}

We only have this type of code when the CONNECTION class is a private class, or to ensure that this class is invisible, and is willing to believe that the code that uses this class is correct to use this usage.

However, the Connection class is publicly used, and there is a possibility that a program that uses the Connection class has a vulnerability, and attempts to close an unmopable connection. Due to this possibility, use throw anomalies is more suitable:

public class Connection {private boolean isOpen = false; public void open () {// ... isOpen = true;} public void close () throws ConnectionException {if (isOpen!) {throw new ConnectionException ( "Can not close a connection that IS not open! ");} // ...}}

Don't use Assertion to ensure the requirements of a message provided by the user

In the following segment, programmers use Assertions to ensure that postal codes have 5 or 9 digits:

Public void processzipcode (string zipcode) {if (zipcode.Length () == 5) {// ...} else if (zipcode.length () == 9) {// ...} else {// bad !! Assert False: "Only 5- and 9-Digit Zip Codes Supported";}}

Assertion should be used to ensure internal consistency, rather than guarantee the correct input. The above code should throw an exception in the error:

Public void processzipcode (string zipcode) throws zipcodeException {if (zipcode.length () == 5) {// ...} else if (zipcode.length () == 9) {// ...} else {throw New ZipCodeException ("Only 5- and 9-Digit Zip Codes Supported");}}

Use assert to ensure the right to assume the internal data structure

The parameters of the private method below are arrays of three intenses. We can use assertion to confirm that this array has the correct length:

Private void showdate (int Array []) {assert (array.length == 3);}

We expect the call to this method to be correct, that is, only an array of length 3, the Assertion statement is now this role. The Java language has a function of the array already checks. This ensures that the program does not read the value other than the array boundary. The role of the Assertion statement in this code is not as important as the role in C or C , but it does not mean This is extra.

Use assertion to check that any method will end when

We look at the following example how to check the final status before the method returns:

Public class connect {private boolean isopen = false; public void open () {// ... isopen = true; // ... assert isopen;} public void close () throws connectionException {if (! isopen) {throw new ConnectionException ("Cannot Close A Connection That IS Not Open!");} // ... isopen = false; // ... assert! Isopen;}}

The benefits of this is that the code inside these methods is complicated or how much modification changes, we can ensure that the method is correct when the method returns.

Check the status that should not happen using Assertion

The following code is this role:

Private int getValue () {if (/ * Something * /) {RETURN 0;} else if (/ * something else * /) {return 1;} else {return 2;}} public void method () {int a = getValue (); // Returns 0, 1, OR 2 IF (a == 0) {// deal with 0 ...} else if (a == 1) {// DEAL WITH 1 ...} Else IF (a == 2) {// deal with 2 ...} else {askERT FALSE: "Impossible: a is out of range";}} This example, GetValue's return value can only be 0, 1, 2, There is no situation in normal, and it is not possible to ensure that this is the most appropriate.

Tip: A good programming habit is to always write a final ELSE statement for each group of if else statements to include all other situations. If you can guarantee that the program will not enter this statement, add an Assert False;

Check the initial state at the beginning of any method using Assertion

In this example, the method processzipcode () must ensure that the format of Zipcode is valid before further processing:

Public void processzipcode (string zipcode) {assert zipcodemapisvalid (); // ...}

Doing so allows the vulnerabilities in the program to be discovered early.

The final principle: there is no

Joining an Assertion statement is very simple, you can join any phase of code written, and the impact on the speed of program running speed is also slight, so if you have doubts about some of the procedures, it is uncertain, Despite the addition of the assertion statement. There is no harm of an Assertion statement that never triggers, but if it is triggered, there is no ASSERTION statement exists, and it is huge for us. Seven, conclude:

We can find that almost all Assertion code looks excess, and this is the feature of the assertion statement. If we find that a Assertion code is essential in the program, then we must use the wrong use. ASSERTION statement. The Assertion statement does not constitute a part of the normal running logic, and the time is remembered that they may not be executed. We should use the assertion statement if it should be used, and the key to considering whether to help improve the robustness of the code, whether it helps the code to provide useful information for the debugging process.

转载请注明原文地址:https://www.9cbs.com/read-110546.html

New Post(0)