Missing Number Treated as Zero to Be Read Again C L55 Subsection
Section 8.3
Exceptions and effort..grab
Getting a program to piece of work under ideal circumstances is commonly a lot easier than making the program robust. A robust program can survive unusual or "exceptional" circumstances without crashing. One approach to writing robust programs is to anticipate the bug that might arise and to include tests in the plan for each possible problem. For instance, a program volition crash if information technology tries to utilise an array chemical element A[i], when i is not inside the declared range of indices for the array A. A robust program must anticipate the possibility of a bad alphabetize and guard against it. Ane way to exercise this is to write the program in a fashion that ensures (as a postcondition of the code that precedes the array reference) that the index is in the legal range. Another style is to examination whether the index value is legal before using it in the assortment. This could exist washed with an if statement:
if (i < 0 || i >= A.length) { ... // Do something to handle the out-of-range index, i } else { ... // Process the assortment element, A[i] } There are some issues with this arroyo. It is difficult and sometimes incommunicable to anticipate all the possible things that might go wrong. Information technology's not always clear what to do when an error is detected. Furthermore, trying to conceptualize all the possible problems can turn what would otherwise be a straightforward algorithm into a messy tangle of if statements.
8.three.1 Exceptions and Exception Classes
We have already seen in Section three.7 that Java provides a neater, more than structured alternative technique for dealing with errors that can occur while a programme is running. The technique is referred to as exception treatment. The word "exception" is meant to be more than general than "fault." It includes any circumstance that arises equally the plan is executed which is meant to exist treated every bit an exception to the normal flow of control of the program. An exception might exist an error, or information technology might just exist a special case that yous would rather not have ataxia up your elegant algorithm.
When an exception occurs during the execution of a program, we say that the exception is thrown. When this happens, the normal menses of the programme is thrown off-track, and the program is in danger of crashing. Withal, the crash tin can be avoided if the exception is caught and handled in some way. An exception can be thrown in 1 part of a program and defenseless in a different role. An exception that is non caught volition generally cause the plan to crash. (More than exactly, the thread that throws the exception will crash. In a multithreaded programme, information technology is possible for other threads to continue even later one crashes. We will cover threads in Affiliate 12. In item, GUI programs are multithreaded, and parts of the program might go on to function even while other parts are not-functional because of exceptions.)
By the way, since Java programs are executed by a Java interpreter, having a programme crash simply means that it terminates abnormally and prematurely. It doesn't hateful that the Java interpreter will crash. In effect, the interpreter catches whatever exceptions that are not caught by the program. The interpreter responds by terminating the program. In many other programming languages, a crashed program will sometimes crash the entire organization and freeze the reckoner until it is restarted. With Java, such system crashes should be incommunicable—which means that when they happen, y'all have the satisfaction of blaming the system rather than your own program.
Exceptions were introduced in Section iii.7, forth with the try..grab statement, which is used to catch and handle exceptions. However, that section did non encompass the complete syntax of effort..catch or the total complexity of exceptions. In this section, we encompass these topics in full item.
When an exception occurs, the matter that is actually "thrown" is an object. This object can carry information (in its instance variables) from the point where the exception occurs to the point where it is caught and handled. This information e'er includes the subroutine phone call stack, which is a list of the subroutines that were beingness executed when the exception was thrown. (Since one subroutine can call another, several subroutines can be active at the same time.) Typically, an exception object too includes an error message describing what happened to cause the exception, and information technology can contain other data as well. All exception objects must belong to a bracket of the standard class coffee.lang.Throwable. In general, each different type of exception is represented by its own subclass of Throwable, and these subclasses are bundled in a fairly complex course bureaucracy that shows the relationship amongst diverse types of exception. Throwable has two direct subclasses, Error and Exception. These two subclasses in turn have many other predefined subclasses. In addition, a programmer can create new exception classes to represent new types of exception.
Most of the subclasses of the class Error represent serious errors within the Java virtual car that should normally cause program termination because there is no reasonable way to handle them. In general, you should not attempt to catch and handle such errors. An instance is a ClassFormatError, which occurs when the Java virtual machine finds some kind of illegal data in a file that is supposed to incorporate a compiled Java form. If that class was beingness loaded every bit part of the programme, then there is actually no way for the program to go on.
On the other paw, subclasses of the grade Exception represent exceptions that are meant to be caught. In many cases, these are exceptions that might naturally be called "errors," just they are errors in the plan or in input data that a programmer tin can anticipate and possibly respond to in some reasonable way. (Yet, you should avoid the temptation of saying, "Well, I'll just put a thing here to take hold of all the errors that might occur, and then my plan won't crash." If y'all don't have a reasonable manner to respond to the fault, it's best just to permit the program crash, considering trying to proceed volition probably but lead to worse things downwards the road—in the worst example, a programme that gives an incorrect respond without giving you whatever indication that the respond might be incorrect!)
The class Exception has its own subclass, RuntimeException. This course groups together many common exceptions, including all those that take been covered in previous sections. For instance, IllegalArgumentException and NullPointerException are subclasses of RuntimeException. A RuntimeException mostly indicates a bug in the programme, which the programmer should fix. RuntimeExceptions and Errors share the holding that a program can simply ignore the possibility that they might occur. ("Ignoring" here means that you are content to let your program crash if the exception occurs.) For example, a program does this every fourth dimension it uses an array reference like A[i] without making arrangements to catch a possible ArrayIndexOutOfBoundsException. For all other exception classes also Error, RuntimeException, and their subclasses, exception-treatment is "mandatory" in a sense that I'll talk over below.
The following diagram is a class hierarchy showing the grade Throwable and merely a few of its subclasses. Classes that require mandatory exception-handling are shown in cherry-red:
The class Throwable includes several instance methods that can be used with whatever exception object. If e is of type Throwable (or one of its subclasses), then e.getMessage() is a function that returns a String that describes the exception. The office e.toString(), which is used by the system whenever information technology needs a cord representation of the object, returns a Cord that contains the name of the class to which the exception belongs equally well as the same string that would be returned by e.getMessage(). And the method e.printStackTrace() writes a stack trace to standard output that tells which subroutines were agile when the exception occurred. A stack trace tin be very useful when you are trying to determine the cause of the problem. Information in the stack trace tin tell you exactly where in the program the exception occurred. (Annotation that if an exception is not caught past the programme, then the default response to the exception prints the stack trace to standard output.)
8.3.two The effort Statement
To catch exceptions in a Java programme, you demand a try statement. We accept been using such statements since Department three.7, but the full syntax of the try argument is more complicated than what was presented there. The attempt statements that nosotros accept used so far had a syntax similar to the following example:
effort { double determinant = M[0][0]*K[i][1] - K[0][ane]*One thousand[1][0]; Arrangement.out.println("The determinant of 1000 is " + determinant); } take hold of ( ArrayIndexOutOfBoundsException eastward ) { System.out.println("Yard is the wrong size to have a determinant."); east.printStackTrace(); } Hither, the computer tries to execute the block of statements following the word "try". If no exception occurs during the execution of this block, and then the "catch" role of the statement is only ignored. All the same, if an exception of type ArrayIndexOutOfBoundsException occurs, then the reckoner jumps immediately to the catch clause of the try statement. This block of statements is said to be an exception handler for ArrayIndexOutOfBoundsException. By handling the exception in this fashion, you prevent information technology from crashing the program. Before the torso of the catch clause is executed, the object that represents the exception is assigned to the variable e, which is used in this example to print a stack trace.
However, the full syntax of the try argument has many options. It will take a while to become through them. For one affair, a try..take hold of argument tin take more ane catch clause. This makes it possible to catch several dissimilar types of exception with one try argument. In the above instance, in add-on to the possible ArrayIndexOutOfBoundsException, in that location is a possible NullPointerException which will occur if the value of M is goose egg. Nosotros can handle both possible exceptions past calculation a second catch clause to the try argument:
try { double determinant = Thou[0][0]*Yard[1][i] - Yard[0][one]*1000[ane][0]; Organization.out.println("The determinant of Grand is " + determinant); } catch ( ArrayIndexOutOfBoundsException e ) { Organisation.out.println("M is the incorrect size to have a determinant."); } catch ( NullPointerException e ) { Organization.out.print("Programming error! Yard doesn't exist." + ); } Hither, the computer tries to execute the statements in the try clause. If no fault occurs, both of the grab clauses are skipped. If an ArrayIndexOutOfBoundsException occurs, the computer executes the body of the first catch clause and skips the second one. If a NullPointerException occurs, it jumps to the second take hold of clause and executes that.
Note that both ArrayIndexOutOfBoundsException and NullPointerException are subclasses of RuntimeException. It'southward possible to catch all RuntimeExceptions with a single catch clause. For example:
try { double determinant = Thousand[0][0]*M[one][i] - M[0][ane]*Thousand[one][0]; Organisation.out.println("The determinant of One thousand is " + determinant); } catch ( RuntimeException err ) { System.out.println("Sorry, an error has occurred."); System.out.println("The error was: " + err); } The grab clause in this try statement will grab whatsoever exception belonging to course RuntimeException or to whatsoever of its subclasses. This shows why exception classes are organized into a class hierarchy. It allows you the option of casting your internet narrowly to catch merely a specific type of exception. Or you tin cast your net widely to catch a broad class of exceptions. Because of subclassing, when there are multiple catch clauses in a try statement, it is possible that a given exception might match several of those grab clauses. For example, an exception of blazon NullPointerException would match grab clauses for NullPointerException, RuntimeException, Exception, or Throwable. In this case, only the first take hold of clause that matches the exception is executed.
Of course, catching RuntimeException would catch many more types of exception than the 2 that nosotros are interested in. It is possible to combine several specific exception types in a single catch clause. For example,
try { double determinant = M[0][0]*K[1][1] - K[0][1]*M[1][0]; System.out.println("The determinant of M is " + determinant); } catch ( NullPointerException | ArrayIndexOutOfBoundsException err ) { System.out.println("Sorry, an error has occurred."); System.out.println("The error was: " + err); } Here, the 2 exception types are combined with a "|", the vertical line graphic symbol that is as well used in the boolean or operator. This example volition catch errors of type NullPointerException or ArrayIndexOutOfBoundsException, and no other types.
The example I've been using here is not realistic, because yous are not very likely to use exception-handling to baby-sit against zippo pointers and bad array indices. This is a example where careful programming is meliorate than exception handling: Only exist certain that your program assigns a reasonable, non-zero value to the array M. You would certainly resent it if the designers of Java forced yous to set up a try..catch argument every time you wanted to use an assortment! This is why handling of potential RuntimeExceptions is not mandatory. At that place are only too many things that might get incorrect! (This also shows that exception-handling does not solve the problem of program robustness. It just gives y'all a tool that will in many cases let you approach the problem in a more organized way.)
I have still not completely specified the syntax of the try statement. The next variation is the possibility of a finally clause at the end of a try statement. With this addition, the syntax of the try statement can be described as:
try { statements } optional-catch-clauses optional-finally-clause Note that the catch clauses are also listed equally optional. The try argument can include goose egg or more catch clauses and, optionally, a finally clause. The endeavor statement must include one or the other. That is, a endeavor statement tin have either a finally clause, or 1 or more catch clauses, or both. The syntax for a catch clause is
catch ( exception-class-names variable-name ) { statements }
where exception-grade-names can be a single exception form or several classes separated by "|". The syntax for a finally clause is
finally { statements } The semantics of the finally clause is that the cake of statements in the finally clause is guaranteed to be executed as the last step in the execution of the endeavor argument, whether or not whatever exception occurs and whether or not any exception that does occur is defenseless and handled. The finally clause is meant for doing essential cleanup that nether no circumstances should exist omitted. One case of this type of cleanup is endmost a network connection. Although y'all don't yet know enough about networking to look at the bodily programming in this case, nosotros can consider some pseudocode:
try { open a network connection communicate over the connection } grab ( IOException east ) { report the error } finally { if the connexion was successfully opened close the connection } The finally clause ensures that the network connection will definitely be closed, whether or not an error occurs during the communication. The pseudocode in this example follows a full general pattern that can exist used to robustly obtain a resource, use the resource, and then release the resource.
The blueprint of obtaining a resource, and then using the resource, and so releasing the resources is very mutual. Note that the resource can only be released if no mistake occurred while obtaining it. And, if it was successfully obtained, and so it should be airtight whether or non an mistake occurs while using information technology. This pattern is so mutual that it leads to one last pick in the try statement syntax. With this option, you simply need lawmaking to obtain the resources, and yous don't need to worry about releasing it. That will happen automatically at the terminate of the effort argument.
In order for this to work, the resources must be represented by an object that implements an interface named AutoCloseable, which defines a unmarried method named shut(), with no parameters. Standard Java classes that represent things like files and network connections already implement AutoClosable. And then does the Scanner class, which was introduced in Subsection 2.4.six. In that department, I showed how to use a Scanner to read from Arrangement.in. Although I didn't do it in that section, information technology's considered good form to close a Scanner later on using it. Here is an case that uses the design in a try argument to brand sure that the Scanner is closed automatically:
try( Scanner in = new Scanner(System.in) ) { // Use the Scanner to read from standard input } catch (Exception e) { // ... some mistake occurred while using the Scanner } The statement that allocates the Scanner goes in parentheses after the give-and-take "try". The statement must take the form of a variable announcement that includes an initialization of the variable. The variable is local to the try statement. (You can actually declare several variables in the parentheses, separated by semicolons.) In this example, we can be sure that in.shut() will definitely be called by the system at the end of the try statement, as long as the Scanner was successfully initialized.
This is all getting quite complicated, and I won't continue the discussion hither. The sample program TryStatementDemo.java demonstrates a try statement with all its options, and information technology includes a lot of comments to aid you understand what can happen when y'all run the program.
8.3.3 Throwing Exceptions
There are times when information technology makes sense for a program to deliberately throw an exception. This is the case when the programme discovers some sort of exceptional or mistake condition, but at that place is no reasonable way to handle the error at the point where the problem is discovered. The program tin can throw an exception in the hope that another part of the program will catch and handle the exception. This can exist washed with a throw statement. Y'all accept already seen an example of this in Subsection 4.iii.viii. In this section, we cover the throw statement more fully. The syntax of the throw argument is:
throw exception-object ; The exception-object must be an object belonging to one of the subclasses of Throwable. Commonly, it will in fact belong to i of the subclasses of Exception. In most cases, information technology will exist a newly constructed object created with the new operator. For instance:
throw new ArithmeticException("Division by zero"); The parameter in the constructor becomes the error message in the exception object; if e refers to the object, the error message can be retrieved by calling eastward.getMessage(). (You might detect this instance a bit odd, because y'all might expect the organisation itself to throw an ArithmeticException when an attempt is made to split up by zero. And then why should a programmer bother to throw the exception? Retrieve that if the numbers that are being divided are of blazon int, so sectionalisation by zero will indeed throw an ArithmeticException. However, no arithmetic operations with floating-point numbers will ever produce an exception. Instead, the special value Double.NaN is used to stand for the result of an illegal functioning. In some situations, you might prefer to throw an ArithmeticException when a existent number is divided by zero.)
An exception tin be thrown either past the system or by a throw statement. The exception is processed in exactly the same way in either case. Suppose that the exception is thrown inside a try statement. If that endeavour statement has a grab clause that handles that type of exception, so the computer jumps to the catch clause and executes it. The exception has been handled. After handling the exception, the calculator executes the finally clause of the effort statement, if at that place is one. It then continues commonly with the rest of the program, which follows the endeavour statement. If the exception is not immediately caught and handled, the processing of the exception volition go on.
When an exception is thrown during the execution of a subroutine and the exception is not handled in the same subroutine, so that subroutine is terminated (subsequently the execution of any pending finally clauses). And then the routine that chosen that subroutine gets a chance to handle the exception. That is, if the subroutine was called within a endeavour argument that has an advisable catch clause, then that catch clause will be executed and the program will go on on unremarkably from in that location. Once again, if the second routine does not handle the exception, then it likewise is terminated and the routine that chosen information technology (if whatsoever) gets the adjacent shot at the exception. The exception volition crash the program only if it passes upwards through the entire chain of subroutine calls without beingness handled. This is called "unwinding the call stack."
A subroutine that might generate an exception tin denote this fact past adding a clause "throws exception-class-name" to the header of the routine. For example:
/** * Returns the larger of the ii roots of the quadratic equation * A*x*10 + B*10 + C = 0, provided it has any roots. If A == 0 or * if the discriminant, B*B - iv*A*C, is negative, then an exception * of type IllegalArgumentException is thrown. */ static public double root( double A, double B, double C ) throws IllegalArgumentException { if (A == 0) { throw new IllegalArgumentException("A tin can't be zero."); } else { double disc = B*B - iv*A*C; if (disc < 0) throw new IllegalArgumentException("Discriminant < zero."); return (-B + Math.sqrt(disc)) / (2*A); } } Every bit discussed in the previous section, the computation in this subroutine has the preconditions that A != 0 and B*B-4*A*C >= 0. The subroutine throws an exception of type IllegalArgumentException when either of these preconditions is violated. When an illegal status is found in a subroutine, throwing an exception is oft a reasonable response. If the plan that called the subroutine knows some good way to handle the error, it can take hold of the exception. If not, the program will crash—and the programmer will know that the program needs to be fixed.
A throws clause in a subroutine heading can declare several dissimilar types of exception, separated past commas. For example:
void processArray(int[] A) throws NullPointerException, ArrayIndexOutOfBoundsException { ... 8.3.4 Mandatory Exception Handling
In the preceding case, declaring that the subroutine root() can throw an IllegalArgumentException is simply a courtesy to potential readers of this routine. This is because handling of IllegalArgumentExceptions is not "mandatory." A routine tin throw an IllegalArgumentException without announcing the possibility. And a program that calls that routine is free either to grab or to ignore the exception, just as a programmer can choose either to catch or to ignore an exception of blazon NullPointerException.
For those exception classes that require mandatory handling, the situation is different. If a subroutine tin can throw such an exception, that fact must be appear in a throws clause in the routine definition. Failing to do so is a syntax error that volition be reported by the compiler. Exceptions that require mandatory handling are called checked exceptions. The compiler will check that such exceptions are handled by the plan.
Suppose that some statement in the body of a subroutine can generate a checked exception, i that requires mandatory treatment. The argument could exist a throw statement, which throws the exception straight, or it could be a telephone call to a subroutine that can throw the exception. In either case, the exception must be handled. This can exist done in 1 of two ways: The starting time way is to place the statement in a try argument that has a catch clause that handles the exception; in this case, the exception is handled within the subroutine, and then that no caller of the subroutine tin can ever see the exception. The second way is to declare that the subroutine can throw the exception. This is washed by adding a "throws" clause to the subroutine heading, which alerts any callers to the possibility that the exception might exist generated when the subroutine is executed. The caller will, in turn, be forced either to handle the exception in a effort statement or to declare the exception in a throws clause in its ain header.
Exception-treatment is mandatory for whatever exception class that is non a subclass of either Fault or RuntimeException. These checked exceptions generally correspond weather that are outside the control of the programmer. For example, they might correspond bad input or an illegal activity taken past the user. There is no manner to avoid such errors, so a robust programme has to exist prepared to handle them. The design of Java makes it impossible for programmers to ignore the possibility of such errors.
Among the checked exceptions are several that tin can occur when using Java's input/output routines. This means that yous tin't fifty-fifty use these routines unless yous understand something about exception-handling. Affiliate 11 deals with input/output and uses checked exceptions extensively.
8.3.5 Programming with Exceptions
Exceptions can be used to help write robust programs. They provide an organized and structured arroyo to robustness. Without exceptions, a program tin can become cluttered with if statements that examination for various possible error conditions. With exceptions, it becomes possible to write a make clean implementation of an algorithm that will handle all the normal cases. The exceptional cases tin exist handled elsewhere, in a grab clause of a endeavour statement.
When a program encounters an exceptional condition and has no way of handling it immediately, the program tin can throw an exception. In some cases, it makes sense to throw an exception belonging to i of Java'due south predefined classes, such as IllegalArgumentException or IOException. However, if there is no standard class that fairly represents the exceptional condition, the programmer can define a new exception class. The new grade must extend the standard class Throwable or 1 of its subclasses. In general, if the programmer does non want to crave mandatory exception treatment, the new class volition extend RuntimeException (or one of its subclasses). To create a new checked exception form, which does require mandatory handling, the programmer can extend one of the other subclasses of Exception or can extend Exception itself.
Here, for example, is a form that extends Exception, and therefore requires mandatory exception handling when it is used:
public grade ParseError extends Exception { public ParseError(String message) { // Create a ParseError object containing // the given bulletin as its error message. super(message); } } The class contains only a constructor that makes information technology possible to create a ParseError object containing a given error message. (The statement "super(bulletin)" calls a constructor in the superclass, Exception. See Subsection 5.6.iii.) Of course the class inherits the getMessage() and printStackTrace() routines from its superclass. If east refers to an object of type ParseError, then the office telephone call eastward.getMessage() will retrieve the error bulletin that was specified in the constructor. Merely the main point of the ParseError class is but to exist. When an object of type ParseError is thrown, it indicates that a certain type of error has occurred. (Parsing, by the way, refers to figuring out the syntax of a string. A ParseError would indicate, presumably, that some string that is beingness processed by the plan does not have the expected grade.)
A throw statement can be used in a program to throw an error of type ParseError. The constructor for the ParseError object must specify an error message. For example:
throw new ParseError("Encountered an illegal negative number."); or
throw new ParseError("The give-and-take '" + discussion + "' is not a valid file name."); Since ParseError is defined equally a bracket of Exception, it is a checked exception. If the throw statement does not occur in a try statement that catches the error, and then the subroutine that contains the throw must declare that it tin can throw a ParseError past adding the clause "throws ParseError" to the subroutine heading. For example,
void getUserData() throws ParseError { . . . } This would not be required if ParseError were defined as a subclass of RuntimeException instead of Exception, since in that case ParseErrors would not be checked exceptions.
A routine that wants to handle ParseErrors can use a try statement with a catch clause that catches ParseErrors. For example:
try { getUserData(); processUserData(); } grab (ParseError pe) { . . . // Handle the error } Note that since ParseError is a subclass of Exception, a catch clause of the form "catch (Exception e)" would too grab ParseErrors, along with any other object of type Exception.
Sometimes, it's useful to shop extra data in an exception object. For example,
grade ShipDestroyed extends RuntimeException { Transport ship; // Which send was destroyed. int where_x, where_y; // Location where transport was destroyed. ShipDestroyed(String bulletin, Transport s, int 10, int y) { // Constructor creates a ShipDestroyed object // carrying an error message plus the data // that the send s was destroyed at location (ten,y) // on the screen. super(message); transport = s; where_x = x; where_y = y; } } Here, a ShipDestroyed object contains an error message and some data virtually a transport that was destroyed. This could be used, for example, in a statement:
if ( userShip.isHit() ) throw new ShipDestroyed("You lot've been hit!", userShip, xPos, yPos); Note that the condition represented by a ShipDestroyed object might non even be considered an error. It could be just an expected interruption to the normal flow of a game. Exceptions can sometimes be used to handle such interruptions neatly.
The power to throw exceptions is particularly useful in writing general-purpose methods and classes that are meant to be used in more than than one program. In this example, the person writing the method or class oft has no reasonable way of handling the fault, since that person has no manner of knowing exactly how the method or class will be used. In such circumstances, a novice programmer is oft tempted to print an error bulletin and forge ahead, merely this is virtually never satisfactory since it can atomic number 82 to unpredictable results downwards the line. Printing an fault bulletin and terminating the plan is about as bad, since it gives the program no chance to handle the error.
The plan that calls the method or uses the form needs to know that the error has occurred. In languages that do not back up exceptions, the merely alternative is to return some special value or to set the value of some global variable to signal that an mistake has occurred. For case, the readMeasurement() function in Subsection 8.2.2 returns the value -ane if the user's input is illegal. Notwithstanding, this merely does whatsoever good if the main plan bothers to test the render value. It is very easy to be lazy most checking for special return values every time a subroutine is called. And in this case, using -i as a signal that an error has occurred makes information technology impossible to allow negative measurements. Exceptions are a cleaner way for a subroutine to react when it encounters an fault.
It is like shooting fish in a barrel to alter the readMeasurement() function to apply exceptions instead of a special return value to signal an error. My modified subroutine throws a ParseError when the user's input is illegal, where ParseError is the subclass of Exception that was divers in a higher place. (Arguably, it might be reasonable to avoid defining a new form by using the standard exception class IllegalArgumentException instead.) The changes from the original version are shown in blood-red:
/** * Reads the user's input measurement from one line of input. * Precondition: The input line is not empty. * Postcondition: If the user's input is legal, the measurement * is converted to inches and returned. * @throws ParseError if the user's input is not legal. */ static double readMeasurement() throws ParseError { double inches; // Full number of inches in user'south measurement. double measurement; // One measurement, // such as the 12 in "12 miles." String units; // The units specified for the measurement, // such every bit "miles." char ch; // Used to peek at side by side character in the user'due south input. inches = 0; // No inches have withal been read. skipBlanks(); ch = TextIO.peek(); /* As long as there is more than input on the line, read a measurement and add the equivalent number of inches to the variable, inches. If an mistake is detected during the loop, end the subroutine immediately by throwing a ParseError. */ while (ch != '\n') { /* Get the adjacent measurement and the units. Before reading anything, make sure that a legal value is there to read. */ if ( ! Character.isDigit(ch) ) { throw new ParseError("Expected to find a number, but found " + ch); } measurement = TextIO.getDouble(); skipBlanks(); if (TextIO.peek() == '\n') { throw new ParseError("Missing unit of measure at end of line."); } units = TextIO.getWord(); units = units.toLowerCase(); /* Convert the measurement to inches and add it to the full. */ if (units.equals("inch") || units.equals("inches") || units.equals("in")) { inches += measurement; } else if (units.equals("foot") || units.equals("feet") || units.equals("ft")) { inches += measurement * 12; } else if (units.equals("g") || units.equals("yards") || units.equals("yd")) { inches += measurement * 36; } else if (units.equals("mile") || units.equals("miles") || units.equals("mi")) { inches += measurement * 12 * 5280; } else { throw new ParseError("\"" + units + "\" is non a legal unit of measure."); } /* Look ahead to see whether the next thing on the line is the stop-of-line. */ skipBlanks(); ch = TextIO.peek(); } // end while return inches; } // finish readMeasurement()
In the principal program, this subroutine is called in a try statement of the course
endeavour { inches = readMeasurement(); } take hold of (ParseError e) { . . . // Handle the error. } The complete program can be found in the file LengthConverter3.java. From the user's point of view, this program has exactly the same behavior equally the program LengthConverter2 from the previous section. Internally, however, the programs are significantly different, since LengthConverter3 uses exception treatment.
Source: https://math.hws.edu/javanotes/c8/s3.html
0 Response to "Missing Number Treated as Zero to Be Read Again C L55 Subsection"
Post a Comment