Chapter 9, the basic principle of violation error Control Java is "The code of form errors will not run". Similar to C , the most ideal for capturing errors is that during the compilation, it is best to try to run the program. However, not all errors can detect during compilation. Some problems must be resolved during operation, let the wrong concincen pass some appropriate information to the recipient to know how the problems encountered correctly. In C and other early language, you can achieve this goal through several procedures. And they are usually established as a specified, rather than as part of the programming language. Typically, we need to return a value or set a flag (bit), the recipient checks these values or signs, and how the specific thing happened. However, over time, it is finally discovered that this practice will fought the paralysis of the programs using a library. They tend to think this way: "Yes, the error may appear in other people's code, but will not be in my code." This consequence is that they generally do not check if there is an error (sometimes the error conditions are really stupid, not worth testing; note 1). On the other hand, if a method is checked, the readability of the code may also be greatly reduced when each time the method is called. Since the programmer may still maintain its own system in these languages, they should have a deep experience on this: If the error is controlled in this way, then when you create a large, strong, easy-to-maintain, will definitely encounter Small obstruction. 1: C programmers study the return value of Printf (). The solution is to exclude all incident in the error control, and mandatory format is correct. This method actually has a long history, because in the 1960s, "violation control" means in the operating system; even dating back to the on Error Goto statement in the Basic language. However, C violation control is based on the ADA, while Java is mainly based on C (although it looks more like Object Pascal). "Exception" expression is an "exception" situation, which is an "abnormality" other than normal. When the problem occurs, we may not know how to solve the specific, but it must not continue to continue with it regardless of everything. At this time, it must be resolutely stopped, and someone should point out what happened, and what kind of countermeasure should be taken. But in order to truly solve the problem, there is not enough information in the local area. Therefore, we need to hand over to the heads of the level, make the correct decision (similar to a command chain). Another benefit of a violation mechanism is to simplify the error control code. We don't have to check a specific error and then control it in multiple places of the program. In addition, it is not necessary to check the error when the method is called (because someone can capture the error here). We only need to handle problems in one place: "Violation Module" or "Violation Controller". This can effectively reduce the amount of code and separate the code for describing the specific operation with the code specifically correcting the error. Under normal circumstances, code for reading, writing, and debugging will become stronger. Since the violation control is forcibly implemented by the Java compiler, there is no need to use a large number of examples prepared by this book without in-depth learning violation control. This chapter introduces you to the code required to properly control the violations, and how to generate your own violations when a method is troublesome. 9.1 Basic violations "violation conditions" indicates that the process should be suspended during any problem occurs. In order to separate violations and ordinary problems, violation conditions are very important factors. In the case of ordinary problems, we have enough information to some extent to some extent, and can solve problems.
In the case of violation conditions, it is impossible to continue because there is no enough information to solve problems in the local area. At this point, the only thing we can do is jumping out of the local environment and entrusting that problem to a more advanced person in charge. This is the case where it is violated. A simple example is "division". If it is divided, it is necessary to check, ensuring that the program does not take, and in that case the division is performed. But what is the difference between the denominator? In that specific method, in the environment we try to solve the problem, we may know how to treat a zero mother. However, if it is a value that is not expected, it cannot be handled, so a violation must be generated, not undecisred. A few things will happen when a violation is created. First, create a violation object according to the way to create a Java object: In the memory "stack", use New to create. Subsequently, stop the current execution path (remember to continue along this path), then release the handle of the violation object from the current environment. At this point, the violation control mechanism takes over everything and starts to find an appropriate place for the execution of the program. This proper place is "illegal controller", its responsibility is to recover from the problem, so that the program either try another execution path or continues. As a simple example of a violation, everyone can think of a object handle named T. Sometimes, the program may pass a handle that has not been initialized. So before a method is called with that object handle, it is best to check. You can send information related to the error to a larger scene, the method is to create a special object and use it to represent our information and "throw" out of our current scene. This is called "a violation" or "throwing a violation." The following is its general form: if (t == null) throw new nullpointRexception (); this is "throwing" a violation. In the current scene, it allows us to abandon further try to solve the problem. This issue will be transferred to other more appropriate places to solve. Quantitatively said that it will be revealed soon. 9.1.1 All variables of violations and any other objects of Java, you need to create a violation in the memory stick in the memory, and you need to call a builder. In all standard violations, there are two builders: the first is the default builder, the second, one string independent variable, so that we can put relevant information in a violation: if (t == null Throw new nullpointerException ("t = null"); later, the string can be extracted with various methods, just like it will be displayed later. Here, keyword Throw will make a series of incredible things like a trick. It first performs a New expression, creating an object within the routine execution range. And, it will, and will call the builder for that object. Subsequently, the object is actually returned from the method - although the type of object is usually not a method designed to return. In order to understand violation control, it can imagine it into another return mechanism - but don't be in this issue, otherwise it will encounter trouble. A violation can be exited from the original scope by "throwing". But will return a value, exit method or scope. However, the similarity returned with ordinary methods is all over, because the place we return is very different from where the place returned from ordinary methods (we ended in an appropriate violation controller, it is from violation " The place that throws "may be quite distant - there is a lot of stages in the calling stack). In addition, we can throw any type of "thrown" object as needed.
Typically, we have to "throw" a different type of violation for each different type of error. Our idea is to save information in a violation object and the selected violation object type, so someone in a larger scene can know how to treat our violations (usually, the only information is the type of illegal object, and the illegal object is saved There is no meaning). 9.2 Capture of violations If a method creates a violation, it must ensure that the violation can be captured and treat it correctly. For Java's violation control mechanism, it is the benefit of allowing us to concentrate on the problem to be solved in one place, then treat an error from the code inside another place. To understand how the violation is captured, you must first grasp the concept of "alert zone". It represents a special code area, it is possible to generate a violation and follow the code used to control those violations. 9.2.1 If the TRY block is within one method, and "throw" an violation (or another method in this method is invited), that method will exit during the violation generation. If you don't want a Throw away method, you can set a special code block inside that method and use it to capture a violation. This is called "TRY block" because it is called in this place "try" various methods. The TRY block belongs to a normal scope, with a TRY key: try {// may generate a violation code} If you use a programming language that does not support violation control, you must use the settings and error detection code. Each method is surrounded - even if the same method is called multiple times. After using the violation control technology, all things can be placed in a TRY block, and all violations are captured at the same location. This will greatly simplify our code and make it more easy to distinguish, because the goals you have to achieve will never be confused with comparative errors. 9.2.2 The violation controller Of course, the generated violation must be aborted to some place. This "place" is a violation controller or a violation control module. Moreover, there must be a corresponding violation controller for each type of violation you want to capture. The Violation Controller is followed by the TRY block and tagged with a Catch (capture) keyword. As shown below: 407-408 Program Each Catch clause - ie the violation controller - is similar to a small method, it needs to be used (and only one) specific types of arguments. The identifier (ID1, ID2, etc.) can be used inside the controller, just as an ordinary method is from variables. We sometimes do not use the identifier at all, because the type of violation has provided sufficient information and can effectively handle violations. But even if not, the identifier must also place. The controller must "immediately" behind the TRY block. If "throw" out a violation, the violation control mechanism will search for the first controller that is consistent with the violation type. Subsequently, it will enter that CATCH scrul, and believe that the violation has been controlled (once the Catch clause ends, the search for the controller will stop). Only match the Catch clause will be executed; it is different from the Switch statement, the latter needs a BREAK command after each case to prevent mishand other statements. Inside the TRY block, please pay attention to a large number of different ways to call may generate the same violation, but only one controller is required. 1. Interrupt and recovery In violation control theory, there are two basic methods. In the Interrupt method (Java and C provide support for this method), we assume that the error is very critical, there is no way to return the violations. No matter who "throws" out a violation, it indicates that there is no way to make mistakes, but also don't want to come back. Another method is called "recovery". It means that the violation controller is responsible to correct the current situation, then obtain an error method, assume that the next will be successfully implemented.
If you use recovery, it means that it still wants to continue to execute after the violation is controlled. In this case, our violation is more like a method call - we use it to set a variety of special environments in Java, producing behavior similar to "recovery" (in other words, this time is not "throwing" out one A violation, but call a method for solving the problem). Alternatively, you can put your TRY block into a while loop, use it to enter the TRY block until the result is satisfactory. From a historical point of view, if the programmer uses the operating system supports recoverable violation control, it will ultimately use the code similar to the interrupt, and skip the recovery process. So although it is very good on the "recovery" surface, it is difficult to be difficult in practical applications. The reasons why the decisiveness may be: Our control module must pay attention to whether a violation is generated, and whether it contains code dedicated to generating location. This makes the code difficult to write and maintain - the large system is especially the case, because the violation may be generated in multiple locations. 9.2.3 Violations in Java, for customers who want to call methods, we must notify them that they may "throw" violations from their own methods. This is a polite approach, only it can enable customer programmers to accurately know what code to write to capture all potential violations. Of course, if you provide the source code, the customer programmer can even check the code, find the corresponding throw statement. But in this way, it is usually not provided with the same source code. To solve this problem, Java provides a special grammatical format (and forced us to adopt) to politely tell the customer to "throw" what violations of "throw", so that the other party is conveniently controlled. This is the "violation specification" we have to tell here, which belongs to a part of the method declared, which is located behind the list of auto-variables (parameters). The violation specification uses an extra keyword: throws; follows all the potential violation types. Therefore, our method definition should look like this: void f () throws tool, toosmall, divzero {// ... If you use the following code: Void f () [// ... it means no It will "throw" violations from the method (except for the type of runtimeException, it may throw from anywhere - will tell later later). However, it is not possible to rely entirely in violation specification - if the method has caused a violation, but does not control it, the compiler will detect this situation and tell us to control violations, or point out a violation from the method "throw" specification. Java can guarantee the correctness of violations (Note 2) in the compile period by insisting on the array of violations from the top to the bottom. 2: This is a significant progress on the basis of C violations, which will not capture errors that do not comply with violations of violations unless they are running. This makes the C violation control mechanism looks not large. We can take a deceptive means in this place: "Trow" is required to have a violation that has occurred. The compiler understands our requirements and forced the user who uses this method as really producing that violation. In practical applications, it can be used as a "placeholder" of that violation. In this way, the actual violation can be conveniently produced, and the existing code is required to modify the existing code. 9.2.4 Capturing all violations We create a controller to capture all types of violations. The specific approach is to capture the basic type of violation type Exception (there are other types of basic violations, but Exception is the basis for almost all programming activities).
As shown below: Catch (Exception E) {system.out.println ("CAUGHT An Exception");} This code can capture any violations, so it is best to place it at the end of the list of controller during actual use, prevent Follow any special violation controllers behind the latter failure. For all violations commonly used by programmers, because the Exception class is their foundation, we will not get information about violations, but you can adjust the basic class throwable from it: String getMessage () get detailed news. String toString () Returns a brief description of the Throwable, including detailed messages (if any). Void PrintStackTrace () Void PrintStackTrace (PrintStream) Prints the call stack path of Throwable and Throwable. The calling stack shows the order in which we bring us to the method of violations. The first version will print a standard error, and the second printed out our selection process. If you work under Windows, you cannot redirect standard errors. Therefore, we are generally willing to use the second version and give the results to System.out; this, the output can be redirected to any path we want. In addition, we can also get another method from the foundation Object of Throwable. For violation control, one of which may be useful is getClass (), its role is to return an object and use it to represent the class of this object. We can use getName () or toString () to query the name of this Class class. Some of the Class objects can also be made, although those operations are unnecessary in violation control. This chapter will explain the Class object in detail later. Here is a special example, which shows the use of the Exception method (if you have difficulty in executing the program, please refer to Chapter 3 3.1.2 "Assignment": 411 Page Program The program is as follows: 411 Up Procedure It can be seen that the method continuously provides a lot of information - each type of information is a subset of the previous type of information. 9.2.5 Re-"Throw" violation In some cases, we want to re-throw the violations you have produced, especially when using Exception to capture all possible violations. Since we already have a handle of the current violation, just simply re-throw the handle. Here is an example: Catch (Exception E) {system.out.println ("A violation has been generated"); throw e;} Re-"throw" out a violation leads to a violation to enter a higher level environment. Any further Catch clause for the same try block will still be ignored. In addition, all things related to the violation object will be reserved, so a higher level of controller for capturing a particular violation type can extract all information from that object. If it is just simply re-throwing the current violation, the information related to the violation in PrintStackTrace () corresponds to the origin of the violation, rather than re-throwing its location. To install a new stack tracking message, you can call FillInstackTrace (), which will return a special violation object. The creation process of this violation is as follows: Pack the current stack of information into the original violation object. It lists it below: 412-413 Page The most important line number is marked in the comment. Note that the 17th line is not set to the comment line. Its output is as follows: 413 Page Program, therefore, no matter how it is true, no matter how it is repeated "throw",
If you mark the 17th line (become a notes), the annotation of the 18th line will be revoked, which will be converted to FillInstackTrace (), the results are as follows: 413 Up Procedures Due to FillInstackTrace (), the 18th line is violated New start. For g () and main (), the Throwable class must appear in the violation specification because FillInstackTrace () generates a handle of a Throwable object. Since Throwable is an Exception's basic class, it is possible to obtain an object that can "throw" (with throwable properties), but is not an Exception. Therefore, the handle used for Exception in main () may lose your own goal. In order to ensure that all things are in an orderly, the compiler forces throwable uses a violation specification. For example, the violation of the following procedures will not be captured in Main (): 414 page program is also possible to re-"throw" from a captured violation. But if this is done, it will be similar to the use of FillInstackTrace (): The information related to the origin of the violation will be lost, and we have left the information related to the new throw. As shown below: 414-415 Program Output as follows: 415 Page Program The last violation is only known to from main (), not from F (). Note that Throwable is not required in any violation specification. Never care about how to clear the previous violation, or any other violations related to it. They are all based on NEW, and the garbage collector will automatically clear. 9.3 Standard Java violation Java contains a class named throwable, which is described in all things that can be used as a violation. Throwable objects have two conventional types (ie "from throwable inheritance"). Among them, ERROR represents compile periods and system errors, we generally do not have to deliberate them (except for special circumstances). Exception is the basic type of "throw" from the class method of any standard Java library. In addition, they can also "throw" from our own approach and running period. For a comprehensive concept of a violation, the best way is to read Java documents provided by http://java.sun.com (of course, first downloading them better). In order to have a probably impression of various violations, this work is quite valuable. But soon, we will find that there is no special place between a violation and the next violation. In addition, the number of violations provided by Java is increasing; in essence, it is meaningless to print them into a book. Any new library that everyone obtained from other places may also provide their own violations. What we need to master is the basic concept, and what can be used in these violations. Java.lang.Exception This is the basic violation of the program captured. Other violations are derived from it. It is important to pay attention to the problem of the name representative of the violation, and the illegal name is usually carefully selected, which can clearly explain what happened. The violation is not all defined in java.lang; some is to provide support for other libraries, such as Util, Net, and IO, we can see this from their full class, or observe what they from inherit. For example, all IO violations are inherited from java.ioException.
9.3.1 Special circumstances of RuntimeException This chapter is: if (t == null) throw new nullpointRexception (); it seems that you must check NULL in each handle passing into a method (because you don't know call Has a valid handle has been passed), which is undoubtedly quite terrible. But fortunately, we don't have to do this - it belongs to a part of the standard runtime check for Java. If a call is sent to a hollow handle, Java will automatically generate a NullPointeredRexception violation. Therefore, the above code is redundant in any case. This category contains a range of violation types. They are all automatically generated by Java, and they do not have to personally do their hand to include them to their own violations. Most easiestly, they all combine together by placing them into the base class named RuntimeException. This is a good inheritance example: it has established a range of common features and behaviors with certain common features. In addition, we don't have to write a violation specification, pointing out that a method may "throw" out a runtimeException because it has assumed that may occur. Since they are used to point out errors in programming, almost no need to specifically capture a "running period violation" --RuntimeException - it will automatically process it by default. If you have to check RuntimeException, our code will become quite complicated. In our own bag, you can choose "throw" out part of the runtimeException. What happens if these violations are not captured? Since the compiler does not force the violation specification to capture them, if you don't capture, a runtimeException may filter out all the ways we arrive in the main () method. In order to experience what happened at this time, please try the following example: 417 Page I have seen, a runtimeException (or anything from it) belongs to a special case, because the compiler does not require these types Violation specification. The output is as follows: java.lang.RuntimeException: from f () at nevercaught.f (nevercaught.java: 9) at nevercaught.g (nevercaught.java: 12) at nevercaught.main (nevercaught.java: 15) So the answer is: If a runtimeException gets all the ways to arrive in main (), it is not captured, then printStackTrace () is called for that violation when the program exits. Note that it may only ignore RuntimeException in your own code because all other controls have been implemented correctly. Because RuntimeException represents a programming error at this time: (1) A errors we cannot capture (for example, receive an empty handle that is passed to your own method by the customer programmer). (2) As a programmer, an error that should be checked in its own code (such as ArrayIndexOfboundException, at this time, you should pay attention to the size of the array). It can be seen that the best practice is to violate in this case because they contribute to the debugging of the program. Another interesting place is that we cannot divide Java violations into a single use tool. Indeed, they are designed to control those hate running period errors - produced by other strengths outside the code control range. However, it also helps to debug some special types of programming errors, those who are not detected by the compiler. 9.4 Creating your own violations is not necessarily to use Java violations.
This must be mastered because you often need to create your own violations to point out a special error that you can generate your library - but when you create a Java grading structure, this error is unpredictable. In order to create your own violation, you must inherit from an existing violation - it is best to approximate the new violation. Inheriting a violation is relatively simple: 418-419 Program inherits When you create a new class: 419 page The key is "Extends Exception", it means: In addition to including an Exception, there are more Meaning. The increased number of code is very small - only two builders have only been added, and the creation of myException is defined. Remember, if we don't explicitly call an underlying class builder, the compiler will automatically call the underlying default builder. In the second builder, by using the super keyword, the base class builder with a string parameter is explicitly invited. The program output results are as follows: 419 Upsence can be seen, in the MyException violation from F () "throw", lack detailed messages. When you create your own violation, you can also take more operations. We can add additional builder and members: 419-421 Page program Added a data member i at this time; simultaneously add a special method, use it to read the value; also added an additional builder, use it Set the value. The output is as follows: 421 Page Due to the violation is just another form of object, it can continue this process to further enhance the ability of violations. But note that they may miss all these enhancements for client programmers who use themselves. Because they may just simply find violations that are ready to generate, do not do anything apart - this is the standard usage of most Java library violations. If this happens, it is possible to create a new violation type, which does hardly contain any code: //: SimpleException.javaclass SimpleException Exception {} ///: ~ It relies on the compiler to create the default builder (will automatically Call the default builder of the base class). Of course, in this case, we won't get a SimpleExce (String) builder, but it does not actually use it. 9.5 Limitations of violations When a method, only violations defined in the basic class versions of the method can be generated. This is an important limit because it means that the code works with the basic class will automatically apply any object derived from the basic class (of course, this belongs to the basic OOP concept), including violations. The following example demonstrates the limit type imposed on a violation (in the compile period): 422-423 Page Program in Inning, you can see that the builder or Event () method points out that you will "throw" a violation, but They don't actually do that. This is legal because it allows us to force users to capture any violations that may be added in the over-covered EVENT () version. The same reason is also applicable to the Abstract method, just like it is displayed in Atbat (). "Interface Storm" is very interesting because it contains a method defined in incoming --Event (), and a method not defined in it. These two methods will "throw" a new type of violation: rainedout. When executed to "StormyNing Extends" and "Implements Storm", you can see that the Event () method in the Storm cannot change the violation interface in Inning to Event ().
Similarly, this design is very reasonable; otherwise, when we operate the basic class, it is impossible to know whether he captured is correct. Of course, if a method defined in Interface is not in the base class, such as Rainhard (), it has no problem when it produces a violation. Restrictions on violations do not apply to builders. In StormyInning, we can see that a builder can "throw" out anything it hopes, regardless of the basic class builder "throw". However, since the basic class builder must be called in some way (here, the default builder will be called automatically), the derivative builder must declare all basic class builder violations in their own violation specification. StormyInning.walk () The reason why it does not compile is that it "throw" has a violation, but inning.walk () will not "throw" out. If this is allowed, you can call Inning.walk (), it will not have to control any violations. However, when replacing a class of inning from Inning, the violation will "throw" out, resulting in the interrupt execution of the code. The replacement of the object can be held in conjunction with the violation specification of the basic type method by forcing the derivative type method. The over-covered EVENT () method shows us that the derivative version of a method can not produce any violation - even if the fundamental version is to produce a violation. Similarly, this is necessary because it does not interrupt the code that has assumed the fundamental version that generates violations. Almost the truth applicable to Atbat (), it will "throw" Popfoul - a violation derived from foul, and the Foul violation is generated by the base class version of Atbat (). In this way, if someone operates Inning in its own code, At the same time, ATBAT () is called, and FOUL violations must be captured. Since Popfoul is derived from Foul, the violation controller (module) will also capture Popfoul. The last interesting place is in main () interior. In this place, if we clearly operate a StormyNing object, the compiler will force us to only capture violations specific to that class. But if we trace the shape to the basic type, the compiler will force us to capture a violation of the basic class. Through all these limitations, the "robust" of violation control code has been greatly improved (notes 3). 3: ANSI / ISO C exerts a similar limit, requiring the derivative method violations to the same violations thrown from the base method, or derive from the latter. In this case, C can actually check the violation specification during compilation. We must recognize this: Although the violation specification is forcibly compliant by the compiler during the inheritance, the violation specification is not part of the method type, and the latter only includes the method name and the self-variable type. Therefore, we cannot cover the method on the basis of violations. In addition, although the violation specification exists in a basic class version of a method, it does not mean that it must exist in the derivative version of the method. This is quite different from the "inheritance" of the method (when inheriting, the method in the basic class must also exist in the derivative class). In other words, the "violation specification interface" for a particular method may become more "narrow" in inheritance and override, but it will not become more "wide" - this is just the opposite of the type interface rules when inherited. . 9.6 Clearing with Finally Whether a violation occurs in the TRY block, we often want to perform some specific code. For some specific operations, this is often encountered, but it is generally unnecessary when recovery memory (because the garbage collector will automatically take everything). In order to achieve this, a Finally clause (notes 4) can be used at the end of all violation controllers.
So the complete violation control section is below: try {// To defend the area: // May "throw" the danger of A, B, or C} Catch (a a a a1) {// controller A} catch (B B1) {// Controller B} CATCH (C C1) {// Controller C} Finally {// Every time, the situation will occur} 4: C violation control does not provide a finally clause because it relies on builder Reach this clearing effect. To demonstrate the Finally clause, please trial: 426 Page Program By the program, we can also know how to cope with the Java violation (similar to the C violation) does not allow this fact that we will return to the violation. If you place your TRY block into a loop, you can establish a condition that must be satisfied before proceeding. A Static counter or other devices can also be added, allowing loops to abandon several different methods. In this way, our program can become more "robust". The output is as follows: 426 Upon procedure, the Finally clause will execute regardless of whether "throw" out of a violation. 9.6.1 Do what is used in a language without "garbage collection" and "automatic call destroyer" mechanism (Note 5), Finally is particularly important, because the programmer can use it to guarantee the correct release of memory - Whether What happened inside the TRY block. However, Java provides a garbage collection mechanism, so the release of memory is almost absolutely not a problem. In addition, it does not have a builder to be called. In this case, when will I use FINALLY in Java? 5: "Destructor" is an antonym of "constructor). It represents a special function, once an object is lost, it usually calls it. We are sure to know where and when to call the destroyer. C provides an automatic destroyer call mechanism, but Delphi's Object Pascal version 1 and 2 do not have this capability (in this language, the meaning of the destroyer has changed). In addition to setting memory back to the original state, Finally is required. For example, we sometimes need to open a file or create a network connection, or draw some things on the screen, and even set a switch in the world, and so on. As shown in the following example: 427-428 Page Program The goal here is to ensure that the switch is turned off when the main () is complete, so the swooff () is placed in the TRY block and the end of each violation controller. But an violation of the result may not be captured here, which will miss sw.off (). However, using Finally, we can put close code from the TRY block only in one place: 428 Program in this, sw.off () has moved to a place. No matter what happens, you will definitely run it. Even if the violation is not captured in the current Catch clause set, Finally is executed before the violation control mechanism goes to a higher level to search for a controller. As shown below: 428-429 Program The program's output shows the specific thing: 429 Up Procedure Calls the Break and Continue statements, the Finally statement will be executed. Please note that with the Break and Continue on the label, Finally eliminates the need for Java to the GOTO jump statement. 9.6.2 Disadvantages: Lost violations are in general, Java's violation implementations are very good. Unfortunately, it still has a shortcomings.
Although there is a crisis in the procedure, it is never ignored, but a violation is still possible to "lose" simply. In a special configuration of the Finally clause, it is possible to happen: 430 page The program output is as follows: 430 Up the program can be seen, there is no sign of Veryimportantexception (very important violation), it is just simple It is replaced by the HohuMexception in the Finally clause. This is a quite serious defect because it means that a violation may be completely lost. And like the pre-example demonstration, this loss is very "natural", it is difficult to be found out of the clue. In contrast, if the second violation is generated before the first violation is controlled, it will be treated as a serious programming error. Perhaps the version after Java will correct this problem (the result is generated by Java 1.1). 9.7 When the builder is written for a violation, we often solve the problem is: "Once a violation is generated, it will be cleared correctly?" Most of the time is very safe, but it is a big problem in the builder. The builder places objects in a secure start state, but it might do some operations - such as open a file. These operations do not get correct clearance unless the user completes the object's use and calls a special cleaning method. If a violation is "throw" inside a builder, these clearing behavior may not occur correctly. All of this means that we must pay attention to when writing builders. Since Finally, I have just learned Finally, everyone may think it is a suitable solution. But things are not so simple, because Finally performs clear code each time - even if we do not want to perform clear code before the clerution is running. Therefore, if you really use Finally, you must set some form of markers at the end of the builder. And as long as the flag is set, don't perform anything in the Finally block. Since this approach is not perfect (there is a need to combine a local code to another place), unless otherwise needed, do not try to make this form in FINALLY. In this example, we created a class called InputFile. Its role is to open a file and then read its line of content (converted to a string). It utilizes FileReader and BufferedReader classes provided by Java standard IO libraries (discussed in Chapter 10). These two classes are very simple, and everyone can now master their basic usage: 431-433 Program This example uses Java 1.1 IO classes. The builder used for the InputFile uses a string parameter that represents the name of the file we want to open. Inside a TRY block, it creates a FileReader with the file name. For FileRead, it is useless unless it is shifted and created with a bufferedReader that can actually and "talk". Note that an advantage of InputFile is that it combines these two actions. If the FileReader builder is unsuccessful, a filenotfoundexception will generate (the file is not found). This violation must be captured separately - this belongs to a special situation we don't want to close the file, because the file has not been successfully opened. All other capture clauses (CATCH) must be turned off because the file is open when it enters those capture clauses (of course, if multiple methods can generate a FileNotFoundException violation, you need to use some tips.
At this point, we can separate different situations into several TRY blocks). Close () method will throw an attempted violation. Even if it is within the code block of another Catch clause, the violation will also capture - for the Java compiler, that Catch clause is just another pair of curly brackets. After the operation is completed, the violation will be re-"throw" out. This is necessary because the implementation of this builder has failed, and we do not want to call the method to assume that the object has been created correctly and valid. In this example, there is no previous marker technology, and the Finally slave is clearly not the correct place to close the file, as this may close it at each builder. Since we want the file to keep an open status when the InputFile object is active, this is not appropriate. The getLine () method returns a string that contains the contents of the next row in the file. It calls readline (), the latter may generate a violation, but that violation will be captured, making getLine () will not have any violations. For violations, a special design problem is to determine a violation of a violation or partial control at this level, or transmitting the same (or different) violations, or simply deliver it. In appropriate, simply transmit a great simplification of our coding work. GetLine () method becomes: string getLine () throws ioException {returnin in.readline ();} But of course, the caller now needs to control any IOException that may be generated. After the user uses the INPUTFILE object, you must call the cleanup () method to release system resources (such as file handles) occupied by BufferedReader and / or FileReader - annotation 6. Whether it should not be cleared unless the InputFile object is used, and it is not necessary to abandon it. Everyone may want to place such a mechanism into a femalize () method, but as pointed out in Chapter 4, it is not always possible to guarantee Finalize () to get the correct call (even if it will call, do not know when to start) . This is a defect of Java - all clearing except memory clearance is automatically performed, so the customer programmer must be aware of the responsibility to ensure that the Finalize () guarantees the correct work. 6: In C , "Destroyer" can help us control this situation. In Cleanup.java, we created an InputFile that opens the same source file used to create a program. At the same time, read the contents of the file and add the corresponding line number. All violations will be captured in main () - although we can choose greater reliability. This example also shows you why you introduce the concept of violations in this place. Violation and Java programming have high integration, mainly because the compiler will force them. Only know how to operate those violations, you can further grasp the knowledge of the compiler. 9.8 Violation Match "Throw" out of a violation, the violation control system searches the "closest" controller in the order of the original preparation. Once the matching controller is found, it is considered that the violation has been controlled and no more search work. Between violations and its controllers, it does not require very precise matching. A derivatic class can match a controller of the basic class, as shown in the following example: 435 Page the program Sneeze violation will be captured by the first CATCH clause. Of course, this is just the first one. However, if we delete the first CATCH clause: 435 Up of the program, the remaining Catch clause can still work because it captures the basic class of Sneeze.