Practice Oracle Java SE 17 Developer 1Z0-829 with free sample questions, timed mock exams, code-reading drills, and detailed answer explanations in IT Mastery.
Oracle Java SE 17 Developer (1Z0-829) focuses on practical Java correctness across types, APIs, collections, streams, exceptions, and concurrency basics.
IT Mastery practice for 1Z0-829 is live now. Use this page to start the web simulator, review the exam snapshot, work through 24 public sample questions, and continue into the full question bank with the same account on web, iOS, iPadOS, macOS, or Android.
Start a practice session for Oracle Java SE 17 Developer (1Z0-829) below, or open the full app in a new tab. For the best experience, open the full app in a new tab and navigate with swipes/gestures or the mouse wheel—just like on your phone or tablet.
Open Full App in a New TabA small set of questions is available for free preview. Subscribers can unlock full access by signing in with the same account they use on web and mobile.
Prefer to practice on your phone or tablet? Download the IT Mastery – AWS, Azure, GCP & CompTIA exam prep app for iOS or IT Mastery app on Google Play (Android) and use the same account across web and mobile.
1Z0-829 questions usually reward the option that follows the exact Java type rules, stream behavior, and exception flow in the snippet instead of relying on intuition about how the code looks.
These sample questions are drawn from the current local bank for this exact exam code. Use them to check your readiness here, then continue into the full IT Mastery question bank for broader timed coverage.
Topic: Additional Oracle Candidate Expectations: Logging and Standard Annotations
A Java 17 project fails to compile after a developer adds an annotation to a utility method:
import java.util.List;
class Reports {
@SafeVarargs
void merge(List<String>... inputs) {
for (var input : inputs) {
System.out.print(input.size());
}
}
}
Which option best explains the cause of the compile error?
merge is an overridable instance method.List<String> cannot appear in a varargs parameter.@SafeVarargs must be placed on the parameter.var cannot be used in an enhanced for loop.Best answer: A
Explanation: The compile error is caused by the invalid use site for @SafeVarargs. In Java 17, the annotation may be used only where overriding cannot invalidate the safety promise: constructors or final, static, or private varargs methods. @SafeVarargs tells the compiler that a varargs method or constructor does not perform unsafe operations on its varargs parameter. Because that promise would not necessarily hold for an overriding method, Java restricts the annotation to constructors and to varargs methods that are not overridable: final, static, or private. The shown merge method is an instance method that is not final or private, so the annotation is rejected at compile time. Making the method final, static, or private, or removing the annotation, would address this specific error.
Topic: Handling Exceptions
In Java 17, a try-with-resources statement opens one resource successfully. The try block throws an exception, and then the resource’s close() method also throws an exception. Which rule applies?
close() exception propagates; the try-block exception is suppressed.Exception.try-block exception propagates; the close() exception is suppressed.close() exception replaces the try-block exception.Best answer: C
Explanation: In try-with-resources, Java preserves the primary exception from the try block when cleanup also fails. The cleanup exception is attached to the primary exception as a suppressed exception. The core rule is that try-with-resources distinguishes the primary exception from exceptions thrown while closing resources. If the try block throws first, that exception is the one propagated. Any exception thrown by an automatically invoked close() call is added to the primary exception’s suppressed-exception list and can be inspected with getSuppressed(). If the try block completed normally, then a close() exception could be the propagated exception instead. This avoids losing the original failure while still preserving cleanup failures for diagnostics.
Topic: Using Java I/O API
A support team reports that a nightly job fails before writing its audit line. The requirement is to overwrite current.txt with incoming.txt when both files already exist, then append one line to current.txt.
Path incoming = Path.of("incoming.txt");
Path current = Path.of("current.txt");
// Before the run, both paths are existing regular files.
Files.copy(incoming, current);
Files.writeString(current, "processed\n", StandardOpenOption.APPEND);
The first file operation throws FileAlreadyExistsException. Which change best fixes the job?
StandardCopyOption.REPLACE_EXISTING to Files.copy().StandardOpenOption.CREATE_NEW to writeString().StandardOpenOption.APPEND to Files.copy().Files.copy() with Files.move(incoming, current).Best answer: A
Explanation: The failure occurs at Files.copy(), before the append operation runs. In NIO.2, copying to an existing target throws FileAlreadyExistsException unless the copy operation includes StandardCopyOption.REPLACE_EXISTING. Files.copy(source, target) creates the target file, but it will not replace an existing target by default. Since both incoming.txt and current.txt already exist, the copy fails immediately. Supplying StandardCopyOption.REPLACE_EXISTING tells the copy operation to overwrite current.txt; then the later Files.writeString() call can append the audit line to the replaced file. StandardOpenOption values apply to opening files for reading or writing, not to Files.copy() replacement behavior.
Topic: Working with Streams and Lambda Expressions
In Java 17, a developer applies anyMatch, allMatch, and noneMatch to an empty Stream<T> with a non-null predicate. Which statement describes the guaranteed result?
anyMatch is false; allMatch and noneMatch are true.Best answer: C
Explanation: The Java Stream matching operations define special results for empty streams. anyMatch returns false because no element can satisfy the predicate, while allMatch and noneMatch return true by vacuous truth. The match operations are terminal operations that may short-circuit. On an empty stream, there are no elements to test, so the predicate is not evaluated. anyMatch asks whether at least one element matches, so it returns false. allMatch asks whether every element matches, which is true when there are no counterexamples. noneMatch asks whether no elements match, which is also true for an empty stream. The key takeaway is that empty streams do not make all match operations behave the same way.
Topic: Controlling Program Flow
In Java 17, which statement correctly describes compile-time checking for loops, labels, and reachability?
break must name an enclosing labeled loop.for accepts any object with iterator().while (true) {} is reachable.continue must name an enclosing labeled loop.Best answer: D
Explanation: Java checks label targets and reachability at compile time. A labeled continue is stricter than a labeled break: it must target an enclosing labeled loop, not just any labeled statement. This prevents continuing to a block or other non-loop statement. For continue label;, the label must refer to an enclosing labeled statement whose body is a loop: while, do, or for. By contrast, break label; may exit an enclosing labeled statement even when that statement is a block. Enhanced for also has a compile-time target rule: the expression must be an array or implement Iterable, not merely have a method named iterator(). Reachability is checked too; a statement immediately after while (true) {} is unreachable unless the loop body has a reachable break that can exit it. The key distinction is that continue resumes loop iteration, so its label must identify a loop target.
Topic: Accessing Databases Using JDBC
A Java SE 17 application has an open Connection con and an int id. It must call a database stored procedure named lookup_total with signature lookup_total(IN id INTEGER, OUT total DECIMAL). The procedure returns no ResultSet. Which JDBC choice correctly applies the statement type rules?
PreparedStatement from con.prepareStatement("call lookup_total(?, ?)"), set parameter 1, then call executeQuery().CallableStatement from con.prepareCall("{call lookup_total(?, ?)}"), set parameter 1, register parameter 2, then call execute().Statement from con.createStatement(), concatenate the id into the call string, then call execute().CallableStatement from con.prepareCall("SELECT lookup_total(?)"), set parameter 1, then call executeQuery().Best answer: B
Explanation: CallableStatement is the JDBC API intended for stored procedures and functions, especially when parameters can be OUT or INOUT. In this scenario, the second procedure parameter is an OUT DECIMAL, so it must be registered before executing the call. JDBC separates statement types by execution need. Statement is for simple static SQL with no bind parameters. PreparedStatement is for precompiled SQL with input placeholders, such as repeated parameterized queries or updates. CallableStatement is for database stored procedure or function calls and supports registering OUT parameters with registerOutParameter before execution. Here, lookup_total has one input parameter and one output parameter, so prepareCall("{call lookup_total(?, ?)}") is the matching API. The closest distractor is PreparedStatement, but it does not provide the stored-procedure OUT parameter handling needed here.
Topic: Working with Arrays and Collections
A service keeps task counts in a map. The following Java 17 troubleshooting snippet compiles, but it prints false, null, 5, and 2, while the developer expected the existing entry to be found and updated. What is the best cause or next fix?
class TaskKey {
String id;
TaskKey(String id) { this.id = id; }
public boolean equals(Object o) {
return o instanceof TaskKey k && id.equals(k.id);
}
public int hashCode() { return id.hashCode(); }
}
public class Demo {
public static void main(String[] args) {
var key = new TaskKey("A");
var counts = new HashMap<TaskKey, Integer>();
counts.put(key, 10);
key.id = "B";
System.out.println(counts.containsKey(key));
System.out.println(counts.replace(key, 99));
System.out.println(counts.merge(key, 5, Integer::sum));
System.out.println(counts.size());
}
}
id stable while the key is stored.LinkedHashMap.put(key, 15).String ids with == in equals().Best answer: A
Explanation: TaskKey is mutable, and id participates in both equals() and hashCode(). After the key is stored, changing id makes the original entry unreachable by normal hash lookup; merge then acts as if the key is absent and inserts another mapping. Hash-based collections require key state used by equals() and hashCode() to remain stable while the key is stored. The entry was inserted when id was "A", so the map placed it according to that hash. After id changes to "B", containsKey() and replace() search using the new hash and do not find the original entry. merge() also sees no matching mapping for that lookup and inserts the provided value, so the size becomes 2. Make the key immutable, or remove the entry before changing the key state and put it back under the new key.
Topic: Handling Date, Time, Text, Numeric, and Boolean Values
A developer is reviewing four possible single-line assignments for a boolean flag. Assume each line appears by itself inside a valid method. Which line fails to compile?
boolean flag = "go" == new String("go");boolean flag = new StringBuilder("go").equals("go");boolean flag = 'g' == 103;boolean flag = new StringBuilder("go") == "go";Best answer: D
Explanation: The failing line uses == between StringBuilder and String. For reference equality, Java requires the operand types to be compatible by casting conversion; these unrelated final classes are not compatible. Java allows == for primitive comparisons and for compatible reference comparisons. A String compared with another String reference compiles, even if it may not be the right content test. A call to equals() also compiles because equals accepts an Object. A char can be numerically promoted and compared with an int. But StringBuilder and String are unrelated final reference types, so new StringBuilder("go") == "go" is rejected at compile time as an invalid comparison. The key takeaway is that == on references is a compile-time type-compatibility check before it is a runtime identity comparison.
Topic: Implementing Localization
A Java 17 application uses this helper to read localized messages. The requirement is to return !key! only when a message key is missing from the selected bundle and its parents. If no bundle can be found for the base name, the application should fail fast.
String message(String baseName, Locale locale, String key) {
try {
var bundle = ResourceBundle.getBundle(baseName, locale);
return bundle.getString(key);
} catch (MissingResourceException e) {
return "!" + key + "!";
}
}
Which refactor is the best fix?
getBundle() outside the try; catch only getString() failures.getString(key) returns null before returning it.baseName before calling getBundle().Best answer: B
Explanation: ResourceBundle.getBundle() and ResourceBundle.getString() can both throw MissingResourceException, but they mean different failures here. The catch block should cover only the acceptable failure: a missing key. Loading the bundle outside that catch preserves fail-fast behavior for a missing bundle. The core issue is exception scope. ResourceBundle.getBundle(baseName, locale) throws MissingResourceException when no suitable bundle can be found. bundle.getString(key) throws the same exception when the key is absent from the bundle and its parent chain. Because the current try covers both calls, it hides a missing bundle by returning a placeholder. Refactor so bundle loading happens before the try, then catch MissingResourceException only around getString(key). The closest trap is treating all MissingResourceException cases the same, even though the scenario requires different behavior for missing bundles and missing keys.
Topic: Managing Concurrent Code Execution
The following Java 17 program includes all required imports. Which statement describes its behavior?
import java.util.*;
import java.util.concurrent.*;
public class CounterDemo {
private static int count = 0;
public static void main(String[] args) throws Exception {
var pool = Executors.newFixedThreadPool(2);
List<Callable<Void>> tasks = List.of(
() -> { for (int i = 0; i < 100_000; i++) count++; return null; },
() -> { for (int i = 0; i < 100_000; i++) count++; return null; }
);
for (var f : pool.invokeAll(tasks)) f.get();
pool.shutdown();
System.out.println(count);
}
}
200000.200000 or a smaller value.count.Best answer: B
Explanation: The program compiles and waits for both tasks to finish, but count++ is not atomic. Because both worker threads update the same shared int without synchronization or an atomic class, some increments can be lost. This is a lost-update race condition. The expression count++ performs a read, an addition, and a write; those steps are not one indivisible operation. If two threads read the same current value, each can compute the same next value and write it back, causing one increment to disappear. Calling Future.get() ensures the main thread waits for task completion and sees completed task effects, but it does not make the updates between worker threads mutually exclusive. The code would need synchronization, a lock, or something like AtomicInteger.incrementAndGet() to guarantee 200000.
Topic: Utilizing Java Object-Oriented Approach
A team is comparing small record declarations for an immutable limit value. Assume each declaration is placed in its own appropriately named .java file. Which declaration does NOT compile in Java 17?
record StaticLimit(int value) {
static final int MIN = 0;
}
record CachedLimit(int value) {
private int cached = value;
}
record CheckedLimit(int value) {
CheckedLimit {
if (value < 0) throw new IllegalArgumentException();
}
}
record DescribedLimit(int value) {
String label() { return "limit=" + value; }
}
StaticLimitCheckedLimitCachedLimitDescribedLimitBest answer: C
Explanation: CachedLimit fails because records cannot declare extra instance fields beyond the private final fields generated for record components. The decisive distinction is static versus instance state: static fields are allowed, but additional per-instance fields are not. A Java 17 record is a restricted class whose instance state is defined by its record components. For record CachedLimit(int value), the component value already defines the record’s instance state. Adding private int cached = value; attempts to add another instance field, which is prohibited in a record declaration. Records may still declare static fields, constructors, and ordinary methods. A compact constructor such as CheckedLimit { ... } may validate or normalize component values, and DescribedLimit may define an instance method that reads the component value. The key takeaway is that records allow behavior and static members, but not extra instance fields.
Topic: Packaging and Deploying Java Code and Using JPMS
The following files are compiled as two named modules with Java 17. All files are in the paths indicated by the comments.
/* inventory.core/module-info.java */
module inventory.core {
exports inventory.api to inventory.app;
opens inventory.impl to inventory.app;
}
/* inventory.core/inventory/api/Item.java */
package inventory.api;
public class Item { public String code() { return "ITEM"; } }
/* inventory.core/inventory/impl/Loader.java */
package inventory.impl;
public class Loader { public static String suffix() { return "-7"; } }
/* inventory.app/module-info.java */
module inventory.app { requires inventory.core; }
/* inventory.app/inventory/app/Main.java */
package inventory.app;
import inventory.api.Item; import inventory.impl.Loader;
public class Main {
public static void main(String[] args) {
System.out.println(new Item().code() + Loader.suffix());
}
}
What is the result when compiling and running inventory.app?
ITEM-7.inventory.impl is opened but not exported.inventory.app cannot read inventory.core.IllegalAccessError at Loader.suffix().Best answer: B
Explanation: The requires inventory.core directive gives inventory.app readability to the core module. However, compile-time access to a public type in another module also requires that the package be exported to the reading module. inventory.impl is opened, not exported, so Loader is not accessible by normal source code. JPMS access requires more than a public class. A module must read the other module, and the package containing the referenced public type must be exported to the reading module. Here, inventory.app reads inventory.core, and inventory.api is exported specifically to inventory.app, so Item is accessible. But inventory.impl is only opened to inventory.app; opens supports reflective access at run time and does not make the package visible for normal compilation. The import of inventory.impl.Loader therefore fails during compilation. The program never reaches a run-time access check.
Topic: Additional Oracle Candidate Expectations: Logging and Standard Annotations
Assume any method snippets are members of a non-final concrete class, and needed imports exist. Which use of a named standard annotation is INVALID in Java 17?
@Override public String toString() { return "x"; }@FunctionalInterface interface Task { void run(); }@Deprecated(since = "17", forRemoval = false) class Legacy {}@SafeVarargs public void addAll(List<String>... lists) {}Best answer: D
Explanation: @SafeVarargs may be applied only to constructors and to varargs methods that cannot be overridden: static, final, or private methods. A public instance method in a non-final class does not meet that rule unless it is explicitly final. Java 17 restricts @SafeVarargs because it asserts that a varargs method with potentially non-reifiable types does not perform unsafe operations. The annotation is valid only on constructors and on variable-arity methods that are static, final, or private. The shown addAll method is variable arity, but it is a public instance method and is not declared final, so the annotation use is a compile-time error. The key takeaway is that @SafeVarargs is about both the varargs parameter and the method’s overridability.
Topic: Handling Exceptions
A service method should return OK when write() succeeds, return RECOVERED when an IOException occurs, rethrow any other unchecked exception, and call audit() exactly once before the method completes. audit() does not throw. The current Java 17 code has a defect:
static String save() {
try {
write();
return "OK";
} catch (IOException e) {
return "RECOVERED";
} finally {
audit();
return "AUDITED";
}
}
Which refactor best fixes the defect?
audit(); before both return statements and remove finally.catch (RuntimeException e) that calls audit(); and rethrows, keeping the finally return.finally after audit();.audit(); in the finally block.Best answer: D
Explanation: The defect is the return inside finally. In Java, finally runs after the try or catch path is chosen, but if finally itself returns, that return replaces the pending return value or thrown exception. Leaving only audit(); in finally preserves the intended paths. Java executes a finally block before a method completes from the associated try or catch. If the finally block completes normally, the earlier return "OK", return "RECOVERED", or unchecked exception propagation continues. If the finally block completes abruptly, such as by executing its own return or throwing an exception, it overrides the pending completion. Here, return "AUDITED"; causes success, recovery, and unchecked failure paths all to complete as "AUDITED". Since audit() does not throw, the fix is to keep cleanup in finally but remove the finally return. The key takeaway is that finally is appropriate for cleanup, not for replacing the method’s selected result path.
Topic: Using Java I/O API
Assume the current directory is writable, contains no symbolic links named a.txt or b.txt, and all necessary imports exist. What is the result of running this code?
public class Test {
public static void main(String[] args) throws Exception {
Path a = Path.of("a.txt");
Path b = Path.of("b.txt");
Files.writeString(a, "A");
Files.writeString(b, "B");
Files.copy(a, b, StandardCopyOption.REPLACE_EXISTING);
Files.writeString(b, "C", StandardOpenOption.APPEND);
Files.writeString(a, "D", StandardOpenOption.CREATE_NEW,
StandardOpenOption.WRITE);
System.out.print(Files.readString(b));
}
}
AC.DC.FileAlreadyExistsException at the copy() call.FileAlreadyExistsException before printing.Best answer: D
Explanation: The copy call succeeds because REPLACE_EXISTING allows b.txt to be overwritten with the contents of a.txt. The append call then adds C to b.txt, but the later CREATE_NEW write targets an existing a.txt, causing FileAlreadyExistsException before anything is printed. NIO.2 file options control whether an existing target is accepted, replaced, appended to, or rejected. The first two writeString() calls use default behavior, creating or truncating the files. Files.copy(a, b, REPLACE_EXISTING) replaces b.txt with the contents of a.txt, so b.txt becomes A. Files.writeString(b, "C", APPEND) appends to b.txt, making it AC. However, Files.writeString(a, "D", CREATE_NEW, WRITE) requires that a.txt not already exist. Since a.txt still exists after a copy operation, this call throws FileAlreadyExistsException. The final print statement is never reached.
Topic: Working with Streams and Lambda Expressions
Assume all imports are shown. A developer changes part of a pipeline to use a parallel stream while collecting results in a shared list:
import java.util.*;
public class Demo {
public static void main(String[] args) {
var ids = List.of(1, 2, 3, 4);
var seq = new ArrayList<Integer>();
ids.stream().forEach(seq::add);
var par = Collections.synchronizedList(new ArrayList<Integer>());
ids.parallelStream().forEach(par::add);
System.out.println(seq);
System.out.println(par);
}
}
What is guaranteed when this code runs?
[1, 2, 3, 4] twice.forEach skips elements in parallel.Best answer: A
Explanation: The sequential stream adds elements in encounter order for this ordered list source. The parallel stream uses forEach, which does not guarantee encounter order, although the synchronized list prevents unsafe concurrent add calls from corrupting the result. The core issue is the difference between thread safety and ordering. Collections.synchronizedList synchronizes individual list operations, so each add call from the parallel stream can complete safely. However, parallelStream().forEach(...) is free to process and apply actions in any order. Since the source list has elements 1, 2, 3, and 4, each element is still processed once, but the order of additions to par is not guaranteed. To preserve encounter order in a parallel stream, use forEachOrdered, recognizing that it may reduce some parallel benefits. The key takeaway is that making shared state thread-safe does not make a parallel stream ordered.
Topic: Controlling Program Flow
No imports are needed. What is the result of compiling and running this Java 17 program with one command-line argument?
class BranchTest {
public static void main(String[] args) {
boolean urgent = args.length > 0;
String label;
if (urgent) {
String prefix = "U";
label = prefix + "1";
} else {
label = "N1";
}
System.out.println(label);
System.out.println(prefix);
}
}
U1 followed by U.N1 followed by U.label might not be initialized.prefix is out of scope.Best answer: D
Explanation: The program fails at compile time because prefix is a local variable whose scope is limited to the if block. The label variable is assigned in both the if and else branches, so definite assignment of label is not the problem. Local variables declared inside a block are in scope only from their declaration to the end of that block. Here, prefix exists only inside the if (urgent) block. Even though the program is run with one argument, Java checks scope at compile time, not based on the actual runtime branch taken. The variable label is definitely assigned because both the if and else branches assign it before it is printed. The later reference to prefix is therefore the compile-time error.
Topic: Accessing Databases Using JDBC
A Java 17 application must execute a database stored procedure. The call has one input parameter and one OUT parameter whose value must be read after execution. Which JDBC type is designed for this need?
CallableStatement from prepareCall()Statement from createStatement()PreparedStatement from prepareStatement()ResultSet from executeQuery()Best answer: A
Explanation: JDBC provides CallableStatement for executing stored procedures. It is the interface that supports callable SQL syntax and methods such as registerOutParameter() for retrieving OUT parameter values. The JDBC statement choice depends on the execution need. Statement is for simple SQL without bind parameters, and PreparedStatement is for precompiled parameterized SQL with input values. When the database operation is a stored procedure call, especially one with an OUT parameter, the JDBC API provides CallableStatement, created with Connection.prepareCall(...). It supports setting input parameters and registering output parameters before execution. A PreparedStatement can use placeholders for input values, but it does not expose the callable-specific OUT parameter API.
Topic: Working with Arrays and Collections
A developer writes a reusable cache. No imports are required. What is the result of compiling and running this Java 17 code?
class Cache<T> {
private T value;
<T> void put(T value) {
this.value = value;
}
T get() { return value; }
}
public class Test {
public static void main(String[] args) {
Cache<String> c = new Cache<>();
c.put("java");
System.out.println(c.get().toUpperCase());
}
}
JAVA.ClassCastException.put due to incompatible type parameters.String.Best answer: C
Explanation: The method declaration <T> void put(T value) introduces a new type parameter scoped to the method. That method T shadows the class T, so assigning the method parameter to the field is not type-safe for all possible type arguments. Generic type parameters have scopes. In Cache<T>, the field value has the class type parameter. But <T> void put(T value) declares a separate method type parameter with the same name, so the parameter is not guaranteed to be the same type as the field. The compiler checks the generic class body independently of the later Cache<String> use, so this.value = value fails at compile time. If the intent is to store a Cache<T> value, the method should be declared as void put(T value) without its own <T> type parameter. The diamond expression is valid because the target type is Cache<String>; the failure happens earlier inside the generic method body.
Topic: Handling Date, Time, Text, Numeric, and Boolean Values
No imports are needed. Given this Java 17 code, what is the result?
public class Limits {
public static void main(String[] args) {
int min = -2_147_483_648;
long next = 2_147_483_648;
long fixed = 2_147_483_648L;
System.out.println(min + "," + next + "," + fixed);
}
}
2_147_483_648 needs an L suffix.-2147483648,2147483648,2147483648.int min; the value is below int range.ArithmeticException before printing.Best answer: A
Explanation: Integer literals without a suffix are treated as int literals first. The positive literal 2_147_483_648 is not valid in that long assignment unless it has an L suffix, even though the variable type is long. Java determines a numeric literal’s type before considering the assignment target. An unsuffixed decimal integer literal is an int literal, with a special allowance for -2_147_483_648 so Integer.MIN_VALUE can be written directly. However, the positive literal 2_147_483_648 cannot be assigned to long unless it is written as a long literal, such as 2_147_483_648L. The fixed declaration is valid, but compilation stops because the earlier next declaration is invalid.
Topic: Implementing Localization
An application runs with Locale.Category.FORMAT set to Locale.US. A developer expects the target French locale to control the localized date text, without changing the JVM-wide default locale. This code still prints an English full date.
var locale = Locale.FRANCE;
var date = LocalDate.of(2025, 7, 14);
var formatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL);
System.out.println(formatter.format(date));
Which next fix is best?
Locale.Category.DISPLAY to Locale.FRANCE.FormatStyle.FULL with FormatStyle.SHORT.formatter = formatter.withLocale(locale); before formatting.date.format(DateTimeFormatter.ISO_LOCAL_DATE).Best answer: C
Explanation: Localized DateTimeFormatter instances use the formatter’s locale to choose locale-specific text and patterns. ofLocalizedDate() uses the default FORMAT locale unless you override it, so the French locale must be attached with withLocale(locale). The core issue is locale selection for a localized formatter. FormatStyle.FULL controls how detailed the localized date pattern is, but it does not specify French by itself. Because the application’s FORMAT default is Locale.US, the formatter formats using English conventions unless a different locale is set on the formatter. DateTimeFormatter is immutable, so withLocale(locale) returns a new formatter that must be assigned or used directly. A suitable fix is to use the formatter returned by withLocale(Locale.FRANCE) before calling format(). Changing DISPLAY locale or switching format styles does not make this formatter use French.
Topic: Managing Concurrent Code Execution
A service uses one Counter instance shared by multiple threads. Which method contains the unsafe locking choice because concurrent calls to that same method do not use the same monitor?
class Counter {
private int count;
private final Object lock = new Object();
void byPrivateLock() { synchronized (lock) { count++; } }
void byThis() { synchronized (this) { count++; } }
void byNewObject() { synchronized (new Object()) { count++; } }
synchronized void bySynchronizedMethod() { count++; }
}
byPrivateLock()byNewObject()byThis()bySynchronizedMethod()Best answer: B
Explanation: A synchronized block protects shared state only when competing threads acquire the same monitor. synchronized (new Object()) creates a fresh monitor for each call, so concurrent callers do not block one another while updating count. The core rule is that Java monitor locking is tied to object identity, not to the text of the synchronized statement. A private final lock field, this, and an instance synchronized method all use a stable monitor for the same Counter instance. In contrast, new Object() allocates a different object every time the method runs, so each thread can acquire its own monitor and execute count++ concurrently. The code compiles, but the locking choice is unsafe for protecting the shared mutable field.
Topic: Utilizing Java Object-Oriented Approach
A developer is converting a small method to use local variable type inference. Imports are not material; the code uses only java.lang types. What is the result when this Java 17 code is compiled and run?
public class Labels {
public static void main(String[] args) {
var prefix = "inv";
var next = null;
next = prefix.toUpperCase();
System.out.print(next);
}
}
INV.null.NullPointerException.Best answer: C
Explanation: Local variable type inference requires an initializer with an inferable type. The first var declaration is valid because "inv" has type String, but null alone has no type for var to infer. Compilation stops before runtime output or exceptions are possible. In Java 17, var is local variable type inference, not dynamic typing. It can be used for a local variable declaration only when an initializer lets the compiler determine a specific compile-time type. var prefix = "inv"; is valid and infers String. var next = null; is invalid because the null literal by itself does not identify a type. A later assignment such as next = prefix.toUpperCase(); cannot be used to infer the variable’s type; inference happens at the declaration.
Topic: Packaging and Deploying Java Code and Using JPMS
A project root contains an empty out directory and exactly the two source files shown below. Comments show file paths. Commands are run from the project root.
// src/com/example/model/Task.java
package com.example.model;
public class Task { public String name() { return "build"; } }
// src/com/example/app/Main.java
package com.example.app;
import com.example.model.Task;
public class Main {
public static void main(String[] args) { System.out.print(new Task().name()); }
}
Which statement is INCORRECT?
Main belongs to com.example.app because of its declaration.package com.example.app; keeps Main in that package because of its directory.Task type directly.javac -d out src/com/example/model/Task.java src/com/example/app/Main.java can compile the files.Best answer: B
Explanation: Java package membership comes from the package declaration, not from the source file’s directory. The directory layout is conventional and useful for locating files, but it does not place a class in a package by itself. Removing the declaration changes Main to the unnamed package. The core concept is the difference between source layout and declared package membership. In Java, the package declaration determines a top-level type’s fully qualified name. Matching directories such as src/com/example/app are a standard convention and help tools and commands organize source and class files, but they do not substitute for the declaration. With both source files listed, javac -d out ... can compile them and write class files under package-based directories below out. If Main.java omits package com.example.app;, its binary name becomes simply Main, not com.example.app.Main. The key takeaway is that package identity is declared in code; directories only support organization and lookup.