Free Java 21 1Z0-830 Practice Questions: Handling Exceptions
Practice 10 free Oracle Java SE 21 Developer Professional (Java 21 1Z0-830) questions on Handling Exceptions, with answers, explanations, and the IT Mastery next step.
Try the IT Mastery web app for a richer interactive practice experience with mixed sets, timed mocks, topic drills, explanations, and progress tracking.
Topic snapshot
| Field | Detail |
|---|---|
| Practice target | Java 21 1Z0-830 |
| Topic area | Handling Exceptions |
| Blueprint weight | 7% |
| Page purpose | Focused sample questions before returning to mixed practice |
How to use this topic drill
Use this page to isolate Handling Exceptions for Java 21 1Z0-830. Work through the 10 questions first, then review the explanations and return to mixed practice in IT Mastery.
| Pass | What to do | What to record |
|---|---|---|
| First attempt | Answer without checking the explanation first. | The fact, rule, calculation, or judgment point that controlled your answer. |
| Review | Read the explanation even when you were correct. | Why the best answer is stronger than the closest distractor. |
| Repair | Repeat only missed or uncertain items after a short break. | The pattern behind misses, not the answer letter. |
| Transfer | Return to mixed practice once the topic feels stable. | Whether the same skill holds up when the topic is no longer obvious. |
Blueprint context: 7% of the practice outline. A focused topic score can overstate readiness if you recognize the pattern too quickly, so use it as repair work before timed mixed sets.
Sample questions
These are original IT Mastery practice questions aligned to this topic area. They are not official Oracle questions, copied live-exam content, or exam dumps. Use them to preview question style and explanation depth before continuing with topic drills, mixed sets, and timed mocks in IT Mastery.
Question 1
Topic: Handling Exceptions
A developer wants one handler for a missing input file and other I/O failures, without catching non-I/O exceptions. Which refactor best fixes this Java 21 code?
import java.io.*;
class Loader {
static void load(String file) {
try (var in = new FileInputStream(file)) {
System.out.println(in.read());
} catch (FileNotFoundException | IOException ex) {
System.err.println("I/O problem: " + ex.getMessage());
}
}
}
Options:
A. Replace the multi-catch with
catch (IOException ex).B. Change it to
catch (Exception | IOException ex).C. Add
catch (FileNotFoundException ex)after the multi-catch.D. Change it to
catch (IOException | FileNotFoundException ex).
Best answer: A
Explanation: Multi-catch alternatives must be unrelated exception types. Because FileNotFoundException extends IOException, listing both in the same multi-catch is illegal. A single catch (IOException ex) handles both conditions while staying limited to I/O failures.
In Java, a multi-catch such as catch (A | B ex) cannot include alternatives where one type is a subclass of another. The compiler rejects FileNotFoundException | IOException because FileNotFoundException already is an IOException. Since the stem requires one shared handler and no non-I/O exceptions, catching IOException directly is the narrow common choice. If different handling were required, ordered separate catches could be used with FileNotFoundException before IOException. Here, the shared handler makes the superclass catch the best refactor.
- Reversing alternatives does not help because the subclass-superclass relationship remains illegal in multi-catch.
- Adding
Exceptioncreates the same related-type problem and also broadens the handler beyond I/O failures. - Adding a later catch leaves the original invalid multi-catch in place, so the code still does not compile.
Question 2
Topic: Handling Exceptions
A developer compiles and runs the following Java 21 code. What is the result?
import java.io.FileNotFoundException;
import java.io.IOException;
public class Demo {
static void read() throws FileNotFoundException {
throw new FileNotFoundException("missing");
}
public static void main(String[] args) {
try {
read();
} catch (IOException | FileNotFoundException e) {
System.out.print("handled");
}
}
}
Options:
A. The code does not compile because the alternatives are related.
B. The code does not compile because
read()declares a checked exception.C. The code prints
handled.D. The code throws
FileNotFoundExceptionat runtime.
Best answer: A
Explanation: A multi-catch may combine exception types only when none of the alternatives is a subclass of another. Here, FileNotFoundException extends IOException, so the catch clause is illegal before runtime behavior is considered.
In Java, multi-catch is intended for unrelated exception alternatives that share the same handling code. The compiler rejects a multi-catch clause such as IOException | FileNotFoundException because catching the superclass IOException already covers FileNotFoundException. This is different from using separate catch clauses, where ordering matters and the more specific type must appear first. Here the program does not get to the point of printing or throwing at runtime because the catch clause itself is invalid.
- Runtime output fails because compilation stops before
System.out.print("handled")can execute. - Uncaught exception fails because a valid
catch (IOException e)would handle aFileNotFoundException. - Checked declaration fails because
read()declaring a checked exception is allowed when it is handled by a valid catch clause.
Question 3
Topic: Handling Exceptions
A Java 21 method body directly calls three methods: load() declares throws IOException, parse() may throw NumberFormatException, and check() may throw AssertionError. The method does not catch any of these exceptions. Under the catch-or-declare rule, which statement is correct?
Options:
A. It must catch or declare only
IOException.B. It must catch or declare all three exception types.
C. It must catch or declare
IOExceptionandNumberFormatException.D. It can ignore
IOExceptionif its caller catches it.
Best answer: A
Explanation: Java requires a method to catch or declare checked exceptions that can escape its body. IOException is checked, so it must be handled or listed in a throws clause. NumberFormatException and AssertionError are unchecked, so the compiler does not require handling or declaration.
The catch-or-declare rule applies to checked exceptions: exception types that are not subclasses of RuntimeException or Error. A method that can let a checked exception escape must either catch it or declare it with throws. In this scenario, IOException is checked, so the method cannot simply omit both a catch block and a compatible throws clause. NumberFormatException is a RuntimeException, and AssertionError is an Error, so both are unchecked. They may be caught or declared, but Java does not require it.
- Runtime exception trap fails because
NumberFormatExceptionis unchecked even though it is an exception. - Error handling trap fails because
AssertionErroris also unchecked for compiler catch-or-declare purposes. - Caller handling trap fails because the current method must still catch or declare a checked exception that can escape it.
Question 4
Topic: Handling Exceptions
A developer sees this compile error at throw ex: unreported exception Exception; must be caught or declared to be thrown. The goal is to keep load declaring only EOFException and SQLException.
import java.io.EOFException;
import java.sql.SQLException;
class Loader {
static void load(String text) throws EOFException, SQLException {
try {
if (text.isEmpty()) throw new EOFException();
if (text.startsWith("db")) throw new SQLException();
} catch (Exception ex) {
ex = normalize(ex);
throw ex;
}
}
static Exception normalize(Exception ex) { return ex; }
}
Which change best fixes the problem?
Options:
A. Change
normalizeto returnRuntimeException.B. Remove the assignment to
exand rethrow it directly.C. Use multi-catch and keep assigning to
ex.D. Add
throws Exceptionto theloadmethod.
Best answer: B
Explanation: Java’s precise rethrow analysis can allow throw ex from a broad catch (Exception ex) to be treated as throwing only the checked exceptions that the try block can throw. That works only if the catch parameter is effectively final. Reassigning ex makes the compiler use its declared type, Exception.
Precise rethrow applies when a catch parameter is not reassigned. In that case, the compiler can infer that ex can only be one of the exceptions thrown in the try block and caught by that handler. Here, those checked exceptions are EOFException and SQLException, so the existing throws clause would be valid if ex were rethrown unchanged. Because ex = normalize(ex); assigns to the catch parameter, ex is no longer effectively final, and throw ex is treated as throwing Exception.
The key takeaway is that preserving a narrow checked-exception contract requires rethrowing the original, effectively final catch parameter.
- Broader declaration would compile, but it violates the stated goal of keeping only
EOFExceptionandSQLException. - Multi-catch reassignment fails because multi-catch parameters are implicitly final and cannot be assigned.
- Runtime return type does not help because
exis still a reassigned variable with declared typeException.
Question 5
Topic: Handling Exceptions
Consider this Java 21 program. No imports are required. What is printed when it runs?
class Demo {
static String run() {
try {
System.out.print("T");
throw new IllegalStateException("try");
} catch (IllegalStateException e) {
System.out.print("C");
return "R";
} finally {
System.out.print("F");
throw new RuntimeException("finally");
}
}
public static void main(String[] args) {
try {
System.out.print(run());
} catch (RuntimeException e) {
System.out.print("E:" + e.getMessage());
}
}
}
Options:
A. Prints
TCFE:tryB. Prints
TCFE:finallyC. Prints
TCFRD. Prints
TFE:finally
Best answer: B
Explanation: The program prints TCFE:finally. The try block throws an exception, the matching catch block begins to return R, but finally executes before that return completes. Because finally throws a new exception, that exception is what main catches.
A finally block runs after the selected try or catch path and before control leaves the method. Here, run() prints T, throws IllegalStateException, enters the matching catch, prints C, and prepares to return R. Before that return can complete, the finally block prints F and throws RuntimeException("finally"). That abrupt completion replaces the pending return, so the outer System.out.print(run()) never receives or prints R. The catch in main handles the RuntimeException from finally and prints E:finally. The key point is that a throwing finally can override both a pending return and an earlier exception path.
- Returned value trap fails because
run()never suppliesRto the outerprintcall. - Skipped catch trap fails because
IllegalStateExceptionmatches thecatchblock beforefinallyexecutes. - Original message trap fails because the new exception from
finallyhas messagefinally.
Question 6
Topic: Handling Exceptions
A developer is reviewing this Java 21 code:
class Service {
static void readFile() throws java.io.IOException { }
static void rejectInput() throws IllegalArgumentException { }
static void process() {
readFile();
rejectInput();
}
}
Which comparison correctly describes what process() must do for these two method calls?
Options:
A.
readFile()requires catch or declaration;rejectInput()does not.B. Both calls require catch or declaration because both methods use
throws.C. Neither call requires handling because neither method body throws an object.
D.
rejectInput()requires catch or declaration;readFile()does not.
Best answer: A
Explanation: Checked exceptions are enforced at compile time for callers. Because readFile() declares java.io.IOException, process() must catch it or declare a compatible exception. IllegalArgumentException is an unchecked RuntimeException, so rejectInput() does not impose a catch-or-declare requirement.
Java’s catch-or-declare rule applies to checked exceptions: exception types that are not subclasses of RuntimeException or Error. A method call whose declared signature includes a checked exception must be enclosed in an applicable catch, or the calling method must declare that exception type or a compatible supertype. Here, java.io.IOException is checked, so process() cannot compile as shown unless it handles or declares it. IllegalArgumentException is unchecked, so its presence in a throws clause documents a possible runtime failure but does not require caller handling. The called method’s empty body does not remove the caller’s compile-time obligation for a declared checked exception.
- Both throws clauses is wrong because unchecked exceptions are not subject to catch-or-declare enforcement.
- Method body only is wrong because callers rely on declared checked exceptions in the method signature.
- Reversed requirement is wrong because
IllegalArgumentExceptionis unchecked andIOExceptionis checked.
Question 7
Topic: Handling Exceptions
A service currently logs only the cleanup failure when both the operation and close() fail:
class Report implements AutoCloseable {
void write() { throw new IllegalStateException("write failed"); }
public void close() { throw new RuntimeException("close failed"); }
}
static void generate() {
var report = new Report();
try {
report.write();
} finally {
report.close();
}
}
The team wants the operation failure to remain the primary exception while still preserving the cleanup failure for diagnostics. Which refactor is best?
Options:
A. Throw the
close()exception because cleanup happened last.B. Use try-with-resources and inspect
getSuppressed().C. Keep
finally; it automatically suppressesclose()failures.D. Catch and ignore the exception thrown by
close().
Best answer: B
Explanation: A finally block can replace the original exception if cleanup also throws. Try-with-resources is designed to preserve the primary exception from the protected block and attach cleanup exceptions as suppressed exceptions.
The core concept is primary versus suppressed exceptions. In the original code, report.write() throws first, but finally still runs; if report.close() also throws, that later exception masks the earlier one. Refactoring to try-with-resources changes the exception relationship: the exception from the try block is thrown as the primary exception, and exceptions from closing resources are available through Throwable.getSuppressed(). This preserves both pieces of diagnostic information without manually managing the cleanup path. The key takeaway is that try-with-resources is the standard fix when cleanup can fail and the operation failure must remain visible.
- Automatic finally suppression is wrong because a throwing
finallyblock can mask the original exception. - Ignoring cleanup failure preserves the primary exception but discards diagnostics the team explicitly wants.
- Throwing cleanup last repeats the defect by making the cleanup failure hide the operation failure.
Question 8
Topic: Handling Exceptions
A service uses two AutoCloseable resources. The current code can report a close failure instead of the real failure from work(). If work() throws, the refactor must preserve that exception, close audit before data, and attach close failures as suppressed exceptions in the order they occur.
class Trace implements AutoCloseable {
private final String name;
Trace(String name) { this.name = name; }
public void close() throws Exception { throw new Exception(name); }
}
void process() throws Exception {
Trace data = new Trace("data");
Trace audit = new Trace("audit");
try {
work(data, audit); // may throw Exception
} finally {
data.close();
audit.close();
}
}
Which refactor best satisfies the requirement?
Options:
A. Catch
Exception, call bothclose()methods, then throw a newExceptionwith the caught exception as its cause.B. Use
try (var data = new Trace("data"); var audit = new Trace("audit")) { work(data, audit); }.C. Use
try { work(data, audit); } finally { audit.close(); data.close(); }.D. Use
try (var audit = new Trace("audit"); var data = new Trace("data")) { work(data, audit); }.
Best answer: B
Explanation: A try-with-resources statement is the best refactor because it guarantees resource cleanup and preserves the primary exception from the try block. Resources close in reverse order of declaration, so declaring data before audit closes audit first and then data.
In Java, try-with-resources closes resources in the opposite order from their declaration. If the try block throws an exception, that exception remains the one propagated, and exceptions thrown by close() are added to it with addSuppressed(). Therefore, declaring data first and audit second gives the required close order: audit then data. If both closes fail after work() fails, the work() exception is thrown with the audit close failure suppressed first, followed by the data close failure.
A manual finally block does not automatically preserve the original exception or suppress close failures.
- Wrong declaration order closes
databeforeaudit, because try-with-resources closes resources in reverse order. - Manual finally cleanup can skip later closes if an earlier
close()throws, and it can replace the primary exception. - Wrapping the exception changes the propagated exception and does not provide the required suppressed-exception behavior.
Question 9
Topic: Handling Exceptions
No imports are needed. What is the result of compiling and running this Java 21 code?
public class RethrowDemo {
static class FirstProblem extends Exception {}
static class SecondProblem extends Exception {}
static void risky(int n) throws FirstProblem, SecondProblem {
if (n == 1) throw new FirstProblem();
throw new SecondProblem();
}
static void process(int n) throws FirstProblem, SecondProblem {
try {
risky(n);
} catch (Exception ex) {
throw ex;
}
}
public static void main(String[] args) throws Exception {
try {
process(1);
} catch (FirstProblem ex) {
System.out.print("first");
} catch (SecondProblem ex) {
System.out.print("second");
}
}
}
Options:
A. It fails to compile because
processmust declareException.B. It prints
first.C. It prints
second.D. It fails to compile because the
SecondProblemcatch is unreachable.
Best answer: B
Explanation: The code compiles and prints first. Java’s precise rethrow analysis can infer that rethrowing ex can only rethrow the checked exceptions thrown from the try block, because ex is not reassigned.
Precise rethrow applies when a catch parameter is final or effectively final. Even though the catch clause catches Exception, the compiler analyzes the try block and sees that risky(n) declares only FirstProblem and SecondProblem as checked exceptions. Therefore, process may legally declare throws FirstProblem, SecondProblem instead of the broader throws Exception. At runtime, process(1) calls risky(1), which throws FirstProblem, and the first matching catch in main prints first.
The key takeaway is that the declared catch type is not always the required rethrow declaration when precise rethrow is available.
- Wrong branch fails because
n == 1causesFirstProblem, notSecondProblem. - Broader declaration is not required because precise rethrow narrows the checked exceptions.
- Unreachable catch is incorrect because
processdeclares both checked exception types, so both handlers are reachable.
Question 10
Topic: Handling Exceptions
A developer is troubleshooting this Java 21 compile-time error at try (sink): the resource variable is not final or effectively final. What is the best next fix?
class LogSink implements AutoCloseable {
LogSink(String name) {}
void write(String msg) {}
public void close() {}
}
static void save(boolean audit) {
var sink = new LogSink("app");
if (audit) sink = new LogSink("audit");
try (sink) {
sink.write("done");
}
}
Options:
A. Catch
Exceptionaround the try-with-resources block.B. Replace it with
try (new LogSink("audit")).C. Choose the name first; assign
sinkonly once.D. Use
try/finally; Java 21 cannot reuse variables.
Best answer: C
Explanation: Java 21 allows an existing local variable in a try-with-resources header only when that variable is final or effectively final. In the snippet, sink is reassigned in the if, so it does not meet that rule. Choose the log name first, then create one resource variable for the try statement.
The core rule is effective finality for resource reuse. Since Java 9, a try-with-resources statement can use an already-declared local variable, such as try (sink), but that variable must not be reassigned after its initial assignment. Here, sink starts as the app sink and may later be reassigned to the audit sink, so the compiler rejects it as a resource. A clean fix is to decide the name first, then construct one LogSink and use that unchanged variable in try (sink). This also avoids losing the first opened resource when audit is true.
- New expression resource fails because a try-with-resources resource is a declaration or eligible variable access, not a bare
newexpression. - Forced try/finally is unnecessary because Java 21 does allow reused resource variables when they are final or effectively final.
- Catching
Exceptiondoes not address the compile error because the problem is variable reassignment, not checked exception handling.
Continue in the web app
Use IT Mastery for interactive Java 21 1Z0-830 practice with mixed sets, timed mocks, topic drills, explanations, and progress tracking.