Page 597 - Introduction to Programming with Java: A Problem Solving Approach
P. 597
14.5 try Block Details
Now that you know the basic idea behind try blocks, it’s time to flesh out some subtle try block details.
try Block Size
Deciding on the size of your try blocks is a bit of an art. Sometimes it’s better to use small try blocks, and sometimes it’s better to use larger try blocks. It’s legal to surround an entire method body with a try block, but that’s usually counterproductive because then dangerous code is harder to identify. In general, you should make your try blocks small enough so that your dangerous code is easily identified.
On the other hand, if you need to execute several related dangerous statements in succession, you should consider surrounding the statements with one inclusive try block rather than surrounding each statement with its own small try block. Multiple small try blocks can lead to cluttered code. One inclusive try block can lead to improved readability. The improved LinePlot program includes both parseInt state- ments in a single try block because they are conceptually related and physically close together. That im- proves readability.
Assume That try Block Statements Are Skipped
If an exception is thrown, the JVM immediately jumps out of the current try block. The immediacy of
the jump means that if there are statements in the try block after the exception-throwing statement, those
statements get skipped. The compiler is a pessimist. It knows that statements inside a try block might
skipped. Consequently, if there’s a try block that contains an assignment to x, the compiler assumes that the assignment is skipped. If there’s no assignment to x outside of the try block and x’s value is needed outside of the try block, you’ll get this compile-time error:
variable x might not have been initialized
If you get that error, usually you can fix it by initializing the variable prior to the try block. Let’s look at an example. . . .
Your goal is to implement a getIntFromUser method that performs robust input for an int value. Your method should prompt the user for an integer, read the entered value as a string, and then convert the string to an int. If the conversion fails, your method should reprompt the user for an integer. If the user eventually enters a valid integer value, getIntFromUser should return it to the calling module.
Figure 14.5 is a first-cut attempt at implementing the getIntFromUser method. It does a good job with the logic, but it contains compile-time errors that are due to the initializations inside the try block. We’ll fix the try block’s errors soon enough, but let’s first explain the try block’s logic.
The try block contains these three lines: valid = false;
x = Integer.parseInt(xStr);
valid = true;
Note how the three-line code fragment assigns valid to false and then turns around and assigns it back
14.5 try Block Details 563
possibly be skipped, and it assumes the worst; that is, it assumes that all statements inside a try block get Apago PDF Enhancer
to true. Strange, eh? Actually, it’s a fairly common strategy to assume one thing, try it out,
and then change the assumption if it’s proven wrong. And that’s what’s happening here. This
code starts by assuming that the user entry is invalid. It calls parseInt to test whether change as
Assume one thing, then
it’s actually valid; that is, it checks to see if the user entry is an integer. If it is valid, the next statement executes, and valid gets set to true. But what happens if the parseInt
required.