3.10. Additional Practice Exercises¶
3.10.1. Exception Analysis¶
Exception Analysis
Sample solutions not included, because "Show Solutions" was not toggled before printing.
Question 1
Given only the following stack trace, explain what each line of the trace reveals about the method call hierarchy and the exception type. Line A is wrapped here for readability.
A. | Exception in thread "main" java.lang.NullPointerException:
| Cannot invoke "String.length()" because "text" is null
B. | at SimpleExample.processText(SimpleExample.java:12)
C. | at SimpleExample.run(SimpleExample.java:8)
D. | at SimpleExample.main(SimpleExample.java:4)
Solution
The method call chain shows:
The program starts in
main(), which callsrun()on line4.run()callsprocessTexton line8. The trace does not reveal the argument expression used in that call.processText()callslength()when the value oftextisnullon line12, causing aNullPointerException.
Further Explanation:
The last line (D) shows the earliest method call represented
in this trace. In this scenario, the program began in the main
method which ran to line 4 of SimpleExample.java. On line 4,
the program called the run method which ran to line 8 of
our code (seen in line C). The run method called processText
on line 8 and processText ran to line 12 which is where
the NullPointerException originated.
Here, the value of text is null, which means it does not
refer to an object. Invoking an instance method through that value
causes NullPointerException.
Question 2
Given only the following stack trace, explain what each line of the trace reveals about the method call hierarchy and the exception type.
Exception in thread "main" java.lang.IllegalArgumentException: Invalid input
at QuizApp.scoreAnswer(QuizApp.java:32)
at QuizApp.gradeQuiz(QuizApp.java:18)
at QuizApp.main(QuizApp.java:7)
Solution
This code throws an IllegalArgumentException. You should attempt to explain
the output in a manner consistent with the previous question.
Question 3
Consider the following simple Java program:
1/**
2 * Example program demonstrating string operations.
3 */
4public class Example {
5
6 /**
7 * The main entry point of the program.
8 *
9 * @param args command-line arguments (not used)
10 */
11 public static void main(String[] args) {
12 String userInput = null;
13 System.out.println("You entered: " + userInput.toUpperCase());
14 System.out.println("Program continues...");
15 } // main
16
17} // Example
Do you anticipate this code will run successfully? If not, explain what kind of error will occur, and why.
Solution
The code will not run successfully. There will be a runtime error
NullPointerExceptionwhen we calltoUpperCaseon variableuserInputwhich containsnull.Since
maindoes not catch the exception, it propagates outside ofmainand crashes the program. Exceptions move up the call stack through calling methods until handled or the program stops.Without using an
ifstatement, rewrite the program so that it prints "Encountered a null value" and then continues.Solution
1/** 2* Example program demonstrating exception handling with NullPointerException. 3*/ 4public class Example { 5 6 /** 7 * The main entry point of the program. 8 * 9 * @param args command-line arguments (not used) 10 */ 11 public static void main(String[] args) { 12 String userInput = null; 13 14 try { 15 System.out.println("You entered: " + userInput.toUpperCase()); 16 } catch (NullPointerException e) { 17 System.out.println("Encountered a null value"); 18 } // try 19 20 System.out.println("Program continues..."); 21 } // main 22 23} // Example
Question 4
Consider the following code:
1/**
2* Mystery program demonstrating when exceptions may occur.
3*/
4public class Mystery {
5
6 /**
7 * The main entry point of the program.
8 *
9 * @param args command-line arguments (not used)
10 */
11 public static void main(String[] args) {
12 new Mystery().start();
13 } // main
14
15 /**
16 * Starts the program by initializing an array and checking a name.
17 */
18 public void start() {
19 String[] names = new String[3];
20 names[0] = "Aisha";
21 names[2] = "Chen";
22 checkName(names[1]);
23 } // start
24
25 /**
26 * Checks if the provided name is valid.
27 *
28 * @param name the name to check
29 */
30 public void checkName(String name) {
31 if (name.length() > 0) {
32 System.out.println("Valid name!");
33 } // if
34 } // checkName
35
36} // Mystery
Predict what exception will be thrown, where, and why.
Solution
Array components of reference type are initialized to
null. No subsequent assignment changed the value ofnames[1]. When we passnames[1]tocheckName, it attempts to calllength()when the value ofnameisnull. ANullPointerExceptionoriginates at that method call.Using a try-catch, how could you modify the code to avoid the crash?
One Possible Solution
1/** 2* Checks whether the given name is valid. 3* 4* @param name the string to check 5*/ 6public void checkName(String name) { 7 try { 8 if (name.length() > 0) { 9 System.out.println("Valid name!"); 10 } // if 11 } catch (NullPointerException npe) { 12 System.out.println("Invalid name"); 13 } // try 14} // checkName
Question 5
Identify two ways the following method could crash:
1/**
2* Determines if a student is eligible based on their name and scores.
3*
4* @param name the student's name
5* @param scores array of scores
6* @return true if the name length is greater than 3 and the first score is above 70
7*/
8public static boolean isEligible(String name, int[] scores) {
9 return name.length() > 3 && scores[0] > 70;
10} //isEligible
Solution
This method can complete abruptly in these cases:
nameisnull→ causes aNullPointerExceptionwhen callingname.length().When
name.length() > 3is true,scores[0]is evaluated. Ifscoresisnull, this causesNullPointerException; if its length is zero, this causesArrayIndexOutOfBoundsException. Otherwise, short-circuit evaluation skips this array access.
Question 6
Consider the following DataParser class that defines a method
called parseAndDivide which accepts an array of strings, iterates
over each string and parses it into an integer. It further divides
100 by the parsed integer and prints out the result.
List at least two things that could go wrong in the code below.
Note: You may need to look up method(s) to see which exceptions they throw (if any).
1/**
2 * Provides utility methods to parse strings and perform division.
3 */
4public class DataParser {
5
6 /**
7 * Parses each string in the input array as an integer and divides 100 by it.
8 *
9 * @param input an array of strings representing integers
10 */
11 public static void parseAndDivide(String[] input) {
12 for (String str : input) {
13 int value = Integer.parseInt(str);
14 int result = 100 / value;
15 System.out.println("100 / " + value + " = " + result);
16 } // for
17 } // parseAndDivide
18
19} // DataParser
Solution
We could get the following exceptions:
NumberFormatException(NFE) - Ifstris not a valid integer (e.g., "apple", "3.14", "", null).Integer.parseInt()expects a well-formed integer string.ArithmeticException- ifvalueis0which would cause a divide by zero.NullPointerException(NPE) - if theinputitself isnull.
Question 7
A. What is the output of the code below?
Note: This is an updated version of the DataParser class
from the previous question.
1public class DataParser {
2 public static void parseAndDivide(String[] input) {
3
4 try {
5 for (int i = 0; i < input.length; i++) {
6 String str = input[i];
7 try {
8 int value = Integer.parseInt(str); // may throw NumberFormatException
9 int result = 100 / value; // may throw ArithmeticException
10 System.out.println("100 / " + value + " = " + result);
11 } catch (ArithmeticException e) {
12 System.out.println("Cannot divide by zero: " + str);
13 } catch (NullPointerException e) {
14 System.out.println("Array elements cannot be null");
15 } // try
16 } // for
17 } catch (NullPointerException npe) {
18 System.out.println("Input array reference cannot be null");
19 } // try
20
21 } // parseAndDivide
22
23 public static void main(String[] args) {
24
25 String[] input1 = new String[] {"3.14", "50", "200"};
26 String[] input2 = null;
27 String[] input3 = new String[] {"200", null};
28
29 DataParser.parseAndDivide(input1);
30 DataParser.parseAndDivide(input2);
31 DataParser.parseAndDivide(input3);
32
33 } // main
34} // DataParser
Solution
The first call throws an uncaught NumberFormatException.
Later calls in main are not reached. JDK frame line numbers
vary by version; the trace has this form:
Exception in thread "main" java.lang.NumberFormatException: For input string: "3.14"
at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:...)
at java.base/java.lang.Integer.parseInt(Integer.java:...)
at java.base/java.lang.Integer.parseInt(Integer.java:...)
at DataParser.parseAndDivide(DataParser.java:9)
at DataParser.main(DataParser.java:30)
B. Explain
In part A, we added try-catch statements, but the code still crashed. Why? How can we fix it?
See if you can fix the code before moving on.
Solution
The code crashed because Integer.parseInt threw a NumberFormatException
that was never caught. That exception propagated out of main and crashed
the program as we saw in the stack trace.
To fix this, we need to add another catch statement to our code.
C. What is the output of the updated code below?
Note: This is an updated version of the DataParser class
from the previous question.
1public class DataParser {
2 public static void parseAndDivide(String[] input) {
3
4 try {
5 for (int i = 0; i < input.length; i++) {
6 String str = input[i];
7 try {
8 int value = Integer.parseInt(str); // may throw NumberFormatException
9 int result = 100 / value; // may throw ArithmeticException
10 System.out.println("100 / " + value + " = " + result);
11 } catch (NumberFormatException e) {
12 System.out.println("Invalid integer input: " + str);
13 } catch (ArithmeticException e) {
14 System.out.println("Cannot divide by zero: " + str);
15 } catch (NullPointerException e) {
16 System.out.println("Array elements cannot be null");
17 } // try
18 } // for
19 } catch (NullPointerException npe) {
20 System.out.println("Input array reference cannot be null");
21 } // try
22
23 } // parseAndDivide
24
25 public static void main(String[] args) {
26
27 String[] input1 = new String[] {"3.14", "50", "200"};
28 String[] input2 = null;
29 String[] input3 = new String[] {"200", null};
30
31 DataParser.parseAndDivide(input1);
32 DataParser.parseAndDivide(input2);
33 DataParser.parseAndDivide(input3);
34
35 } // main
36} // DataParser
Solution
The output is:
Invalid integer input: 3.14
100 / 50 = 2
100 / 200 = 0
Input array reference cannot be null
100 / 200 = 0
Invalid integer input: null
Question 8
Take a few moments to review the code below:
1try {
2 int n = Integer.parseInt(args[0]);
3} catch (NumberFormatException e) {
4 System.out.println("Invalid number");
5} // try
6
7System.out.println("The value of n is: " + n);
Why won't this code compile?
Solution
This is a compile-time error related to scoping. See section 3.6 ("Regarding Scope") for more examples.
The variable
nis declared inside thetryblock and is not visible outside. The lineSystem.out.println("The value of n is: " + n);tries to accessnout of scope, where it doesn't exist.Refactor the code using two different strategies to fix it:
Using strategy 1 (move dependent code inside the
tryblock).Using strategy 2 (extend the scope by declaring outside the
tryblock but safely handle exceptions after the block.)
Solution
Strategy 1:
1try { 2 int n = Integer.parseInt(args[0]); 3 System.out.println("The value of n is: " + n); 4} catch (NumberFormatException e) { 5 System.out.println("Invalid number"); 6} // try
Strategy 2:
1int n = 0; 2boolean success = false; 3 4try { 5 n = Integer.parseInt(args[0]); 6 success = true; 7} catch (NumberFormatException e) { 8 System.out.println("Invalid number"); 9} // try 10if (success) { 11 System.out.println("The value of n is: " + n); 12} // if
Which strategy (1 or 2) is preferred? Why?
Solution
Prefer strategy 1 here: it keeps the dependent statement with the operation that produces its value and needs no success flag. Strategy 2 is useful when later code needs the variable, but that code must account for failure to obtain a value.
Question 9
Explain the difference between a checked and an unchecked exception in Java.
Solution
Checked exceptions are exceptions that the compiler requires you to catch or declare with
throwswhen they can escape a method. Examples includeIOExceptionandFileNotFoundException.Unchecked exceptions are exceptions that the compiler does not require you to handle. They usually indicate programming errors, such as
NullPointerExceptionorArrayIndexOutOfBoundsException. These examples are subclasses ofRuntimeException. The unchecked exception classes also includeErrorand its subclasses; all other exception classes are checked.Identify which of the two programs below will not compile.
Code Snippet A:
1int[] numbers = {1, 2, 3}; 2System.out.println(numbers[5]); // ArrayIndexOutOfBoundsException
Code Snippet B:
1File file = new File("notes.txt"); 2Scanner scanner = new Scanner(file); // FileNotFoundException 3System.out.println(scanner.nextLine());
Solution
Code Snippet A will compile successfully but will throw an
ArrayIndexOutOfBoundsExceptionat runtime. This is an unchecked exception. Java does not require you to handle it at compile time.Code Snippet B will fail to compile unless you handle or declare the exception. Because
FileNotFoundExceptionis a checked exception, the compiler enforces handling it with a try-catch or throws.
3.10.2. Parsons Problems¶
Parsons Problems
Sample solutions not included, because "Show Solutions" was not toggled before printing.
Practice the exception-handling patterns from this chapter. Each problem is independent. Some ask for a complete method; others provide a method signature and ask only for its body. Assume methods belong to an enclosing class. Review Handling Exceptions (Try-Catch), Regarding Scope, and Explicitly Throwing Exceptions & Exception Propagation as needed.
Use every correct block once and leave the incorrect block unused. Arrange blocks vertically and set their indentation. Level zero is the left edge of the requested fragment; each additional level represents four spaces. For method-body fragments, add the enclosing method's indentation when inserting the fragment into a class. Preserve relative indentation within each block.
Use the interactive controls or open a text version to work on paper or without JavaScript. Letters identify whole blocks. Sample solutions are available by opening their dropdowns. Use Show Solutions to hide or show those dropdowns, including when printing.
Problem 1: Guard before dereferencing
Construct nameLength. Return with zero when name is null;
otherwise return with its length. Check for null before invoking an
instance method.
Text version of Problem 1
Construct nameLength. Return with zero when name is null;
otherwise return with its length. Check for null before invoking an
instance method.
Write the letters of the correct blocks in order and give each block an indentation level. Leave incorrect blocks unused and preserve relative indentation within each block.
Block A
if (name == null) {
Block B
public static int nameLength(String name) {
Block C
return 0;
Block D
return name.length();
Block E
} // if
Block F
} // nameLength
Block G
if (name.equals(null)) {
Text version of Problem 1
Construct nameLength. Return with zero when name is null;
otherwise return with its length. Check for null before invoking an
instance method.
Write the letters of the correct blocks in order and give each block an indentation level. Leave incorrect blocks unused and preserve relative indentation within each block.
Block A
if (name == null) {
Block B
public static int nameLength(String name) {
Block C
return 0;
Block D
return name.length();
Block E
} // if
Block F
} // nameLength
Block G
if (name.equals(null)) {
Sample solution for Problem 1
Block order: B, A, C, E, D, F.
Indentation levels: 0, 1, 2, 1, 1, 0.
public static int nameLength(String name) {
if (name == null) {
return 0;
} // if
return name.length();
} // nameLength
The guard compares the reference value with null without
dereferencing it. The early return prevents the later method call when
name does not refer to an object. Calling name.equals(null)
cannot perform this guard: it throws NullPointerException when the
value of name is null.
Problem 2: Catch and continue
Construct the body of public static void printNumber(String
text). Print the parsed integer, or print Invalid integer if
parsing throws NumberFormatException. Then print Done in
either case. The argument may be null.
Text version of Problem 2
Construct the body of public static void printNumber(String
text). Print the parsed integer, or print Invalid integer if
parsing throws NumberFormatException. Then print Done in
either case. The argument may be null.
Write the letters of the correct blocks in order and give each block an indentation level. Leave incorrect blocks unused and preserve relative indentation within each block.
Block A
System.out.println("Done");
Block B
} // try
Block C
System.out.println(Integer.parseInt(text));
Block D
try {
Block E
System.out.println("Invalid integer");
Block F
} catch (NumberFormatException e) {
Block G
} catch (NullPointerException e) {
Text version of Problem 2
Construct the body of public static void printNumber(String
text). Print the parsed integer, or print Invalid integer if
parsing throws NumberFormatException. Then print Done in
either case. The argument may be null.
Write the letters of the correct blocks in order and give each block an indentation level. Leave incorrect blocks unused and preserve relative indentation within each block.
Block A
System.out.println("Done");
Block B
} // try
Block C
System.out.println(Integer.parseInt(text));
Block D
try {
Block E
System.out.println("Invalid integer");
Block F
} catch (NumberFormatException e) {
Block G
} catch (NullPointerException e) {
Sample solution for Problem 2
Block order: D, C, F, E, B, A.
Indentation levels: 0, 1, 0, 1, 0, 0.
try {
System.out.println(Integer.parseInt(text));
} catch (NumberFormatException e) {
System.out.println("Invalid integer");
} // try
System.out.println("Done");
Normal parsing skips the handler. A parsing failure enters the
NumberFormatException handler, after which execution continues with
Done. Even a null argument to Integer.parseInt causes
NumberFormatException; a NullPointerException handler would not
catch it.
Problem 3: Use a parsed value within its scope
Construct the body of public static void printNext(String text).
Parse text into a local variable n, then print n + 1 only
if parsing succeeds. Otherwise print No number. Valid input
represents an integer smaller than Integer.MAX_VALUE.
Text version of Problem 3
Construct the body of public static void printNext(String text).
Parse text into a local variable n, then print n + 1 only
if parsing succeeds. Otherwise print No number. Valid input
represents an integer smaller than Integer.MAX_VALUE.
Write the letters of the correct blocks in order and give each block an indentation level. Leave incorrect blocks unused and preserve relative indentation within each block.
Block A
try {
Block B
System.out.println("No number");
Block C
} // try
Block D
System.out.println(n + 1);
Block E
System.out.println(n + 1);
Block F
} catch (NumberFormatException e) {
Block G
int n = Integer.parseInt(text);
Text version of Problem 3
Construct the body of public static void printNext(String text).
Parse text into a local variable n, then print n + 1 only
if parsing succeeds. Otherwise print No number. Valid input
represents an integer smaller than Integer.MAX_VALUE.
Write the letters of the correct blocks in order and give each block an indentation level. Leave incorrect blocks unused and preserve relative indentation within each block.
Block A
try {
Block B
System.out.println("No number");
Block C
} // try
Block D
System.out.println(n + 1);
Block E
System.out.println(n + 1);
Block F
} catch (NumberFormatException e) {
Block G
int n = Integer.parseInt(text);
Sample solution for Problem 3
Block order: A, G, D, F, B, C.
Indentation levels: 0, 1, 1, 0, 1, 0.
try {
int n = Integer.parseInt(text);
System.out.println(n + 1);
} catch (NumberFormatException e) {
System.out.println("No number");
} // try
The declaration and dependent output belong in the same try block.
If parsing fails, execution skips the dependent output. The catch block
is a separate scope: using n there is a compile-time error, even
though the declaration appears earlier in the source.
Problem 4: Distinguish parsing and arithmetic failures
Construct the body of public static void divide(String text).
Parse text into value and print the integer quotient 100 /
value. Print Invalid integer for a parsing failure and Zero
divisor for division by zero. Use separate handlers; either order
of the two handlers is acceptable.
Text version of Problem 4
Construct the body of public static void divide(String text).
Parse text into value and print the integer quotient 100 /
value. Print Invalid integer for a parsing failure and Zero
divisor for division by zero. Use separate handlers; either order
of the two handlers is acceptable.
Write the letters of the correct blocks in order and give each block an indentation level. Leave incorrect blocks unused and preserve relative indentation within each block.
Block A
System.out.println(100 / value);
Block B
int value = Integer.parseInt(text);
Block C
} catch (ArithmeticException e) {
System.out.println("Invalid integer");
Block D
try {
Block E
} catch (ArithmeticException e) {
System.out.println("Zero divisor");
Block F
} catch (NumberFormatException e) {
System.out.println("Invalid integer");
Block G
} // try
Text version of Problem 4
Construct the body of public static void divide(String text).
Parse text into value and print the integer quotient 100 /
value. Print Invalid integer for a parsing failure and Zero
divisor for division by zero. Use separate handlers; either order
of the two handlers is acceptable.
Write the letters of the correct blocks in order and give each block an indentation level. Leave incorrect blocks unused and preserve relative indentation within each block.
Block A
System.out.println(100 / value);
Block B
int value = Integer.parseInt(text);
Block C
} catch (ArithmeticException e) {
System.out.println("Invalid integer");
Block D
try {
Block E
} catch (ArithmeticException e) {
System.out.println("Zero divisor");
Block F
} catch (NumberFormatException e) {
System.out.println("Invalid integer");
Block G
} // try
Sample solution for Problem 4
Block order: D, B, A, F, E, G.
Indentation levels: 0, 1, 1, 0, 0, 0.
try {
int value = Integer.parseInt(text);
System.out.println(100 / value);
} catch (NumberFormatException e) {
System.out.println("Invalid integer");
} catch (ArithmeticException e) {
System.out.println("Zero divisor");
} // try
Other accepted arrangements may also be valid.
Parsing and integer division can fail for different reasons, so each handler reports its own failure. Only the matching handler runs. These exception classes are unrelated by inheritance, so reversing the handlers preserves behavior. The distractor catches division by zero but reports the wrong cause.
Problem 5: Recover for each input
Construct the body of public static void printNumbers(String[]
input). Assume input is not null. Process its elements in
order, printing each parsed integer or Invalid integer for an
element that cannot be parsed. Continue with later elements after a
failure, including when an element is null.
Text version of Problem 5
Construct the body of public static void printNumbers(String[]
input). Assume input is not null. Process its elements in
order, printing each parsed integer or Invalid integer for an
element that cannot be parsed. Continue with later elements after a
failure, including when an element is null.
Write the letters of the correct blocks in order and give each block an indentation level. Leave incorrect blocks unused and preserve relative indentation within each block.
Block A
for (String text : input) {
Block B
} // try
Block C
try {
Block D
} // for
Block E
} catch (NumberFormatException e) {
Block F
System.out.println("Invalid integer");
Block G
System.out.println("Invalid integer");
return;
Block H
System.out.println(Integer.parseInt(text));
Text version of Problem 5
Construct the body of public static void printNumbers(String[]
input). Assume input is not null. Process its elements in
order, printing each parsed integer or Invalid integer for an
element that cannot be parsed. Continue with later elements after a
failure, including when an element is null.
Write the letters of the correct blocks in order and give each block an indentation level. Leave incorrect blocks unused and preserve relative indentation within each block.
Block A
for (String text : input) {
Block B
} // try
Block C
try {
Block D
} // for
Block E
} catch (NumberFormatException e) {
Block F
System.out.println("Invalid integer");
Block G
System.out.println("Invalid integer");
return;
Block H
System.out.println(Integer.parseInt(text));
Sample solution for Problem 5
Block order: A, C, H, E, F, B, D.
Indentation levels: 0, 1, 2, 1, 2, 1, 0.
for (String text : input) {
try {
System.out.println(Integer.parseInt(text));
} catch (NumberFormatException e) {
System.out.println("Invalid integer");
} // try
} // for
Placing the try-catch inside the loop gives each element its own recovery path. After the handler finishes, the next iteration can begin. The distractor reports the failure but returns from the entire method; it prevents later elements from being processed.
Problem 6: Reject an invalid argument
Construct requirePositive. Throw IllegalArgumentException
with message count must be positive if count is zero or
negative. Otherwise return with count. Do not catch the exception in
this method.
Text version of Problem 6
Construct requirePositive. Throw IllegalArgumentException
with message count must be positive if count is zero or
negative. Otherwise return with count. Do not catch the exception in
this method.
Write the letters of the correct blocks in order and give each block an indentation level. Leave incorrect blocks unused and preserve relative indentation within each block.
Block A
} // requirePositive
Block B
public static int requirePositive(int count) {
Block C
throw new IllegalArgumentException("count must be positive");
Block D
return count;
Block E
if (count <= 0) {
Block F
} // if
Block G
new IllegalArgumentException("count must be positive");
Text version of Problem 6
Construct requirePositive. Throw IllegalArgumentException
with message count must be positive if count is zero or
negative. Otherwise return with count. Do not catch the exception in
this method.
Write the letters of the correct blocks in order and give each block an indentation level. Leave incorrect blocks unused and preserve relative indentation within each block.
Block A
} // requirePositive
Block B
public static int requirePositive(int count) {
Block C
throw new IllegalArgumentException("count must be positive");
Block D
return count;
Block E
if (count <= 0) {
Block F
} // if
Block G
new IllegalArgumentException("count must be positive");
Sample solution for Problem 6
Block order: B, E, C, F, D, A.
Indentation levels: 0, 1, 2, 1, 1, 0.
public static int requirePositive(int count) {
if (count <= 0) {
throw new IllegalArgumentException("count must be positive");
} // if
return count;
} // requirePositive
The guard rejects both zero and negative values. The throw statement
completes this method abruptly, so rejected values never reach the
return statement. Allocating an exception object alone does not throw
it. Because IllegalArgumentException is unchecked, a throws
clause is not required.
Problem 7: Handle a checked exception
Assume the enclosing class already defines static int readScore(String
filename) throws FileNotFoundException. It returns with an integer score from
a file or throws FileNotFoundException when the file cannot be opened.
For these exercises, assume no other failures. Import
java.io.FileNotFoundException.
Construct the body of public static void printScore(String
filename). Print the score returned by readScore(filename). If
the file cannot be opened, print Missing file. Handle the checked
exception within this method.
Text version of Problem 7
Construct the body of public static void printScore(String
filename). Print the score returned by readScore(filename). If
the file cannot be opened, print Missing file. Handle the checked
exception within this method.
Write the letters of the correct blocks in order and give each block an indentation level. Leave incorrect blocks unused and preserve relative indentation within each block.
Block A
System.out.println("Missing file");
Block B
try {
Block C
} catch (RuntimeException e) {
Block D
int score = readScore(filename);
Block E
System.out.println(score);
Block F
} // try
Block G
} catch (FileNotFoundException e) {
Text version of Problem 7
Construct the body of public static void printScore(String
filename). Print the score returned by readScore(filename). If
the file cannot be opened, print Missing file. Handle the checked
exception within this method.
Write the letters of the correct blocks in order and give each block an indentation level. Leave incorrect blocks unused and preserve relative indentation within each block.
Block A
System.out.println("Missing file");
Block B
try {
Block C
} catch (RuntimeException e) {
Block D
int score = readScore(filename);
Block E
System.out.println(score);
Block F
} // try
Block G
} catch (FileNotFoundException e) {
Sample solution for Problem 7
Block order: B, D, E, G, A, F.
Indentation levels: 0, 1, 1, 0, 1, 0.
try {
int score = readScore(filename);
System.out.println(score);
} catch (FileNotFoundException e) {
System.out.println("Missing file");
} // try
The call can throw the checked exception FileNotFoundException. This
method catches it and reports the failure. Catching RuntimeException
would not satisfy the compiler: it does not cover
FileNotFoundException, and this method declares no throws
clause.
Problem 8: Propagate to a caller that handles the failure
Assume the enclosing class already defines static int readScore(String
filename) throws FileNotFoundException. It returns with an integer score from
a file or throws FileNotFoundException when the file cannot be opened.
For these exercises, assume no other failures. Import
java.io.FileNotFoundException.
The enclosing class also contains this caller:
public static void reportScore(String filename) {
try {
System.out.println(loadScore(filename));
} catch (FileNotFoundException e) {
System.out.println("Missing file");
} // try
} // reportScore
Construct loadScore to call readScore(filename), store the
result in score, and return with it. Let FileNotFoundException
propagate to the supplied caller. Do not catch it or replace a
missing score with a default value.
Text version of Problem 8
Construct loadScore to call readScore(filename), store the
result in score, and return with it. Let FileNotFoundException
propagate to the supplied caller. Do not catch it or replace a
missing score with a default value.
Write the letters of the correct blocks in order and give each block an indentation level. Leave incorrect blocks unused and preserve relative indentation within each block.
Block A
return score;
Block B
} // loadScore
Block C
public static int loadScore(String filename)
throws FileNotFoundException {
Block D
int score = readScore(filename);
Block E
public static int loadScore(String filename) {
Text version of Problem 8
Construct loadScore to call readScore(filename), store the
result in score, and return with it. Let FileNotFoundException
propagate to the supplied caller. Do not catch it or replace a
missing score with a default value.
Write the letters of the correct blocks in order and give each block an indentation level. Leave incorrect blocks unused and preserve relative indentation within each block.
Block A
return score;
Block B
} // loadScore
Block C
public static int loadScore(String filename)
throws FileNotFoundException {
Block D
int score = readScore(filename);
Block E
public static int loadScore(String filename) {
Sample solution for Problem 8
Block order: C, D, A, B.
Indentation levels: 0, 1, 1, 0.
public static int loadScore(String filename)
throws FileNotFoundException {
int score = readScore(filename);
return score;
} // loadScore
The throws clause declares a possible checked exception; it does not
throw anything by itself. If readScore throws, loadScore
propagates that exception and skips its return statement. The supplied
caller catches the exception. Omitting the declaration is a compile-time
error even though a caller has a handler.