This Quick Reference is for candidates preparing for Oracle Java SE 17 Developer (1Z0-829). Use it as a compact review of Java 17 syntax, core APIs, and exam-style distinctions. It is independent exam-prep support and is not affiliated with Oracle.
High-Yield Java 17 Exam Map
| Area | Know cold | Common exam traps |
|---|
| Language basics | primitives, wrappers, operators, control flow, var, text blocks | numeric promotion, compound assignment casts, == vs equals, var limitations |
| OOP | inheritance, overriding, access, interfaces, enums, nested types | static hiding vs overriding, initialization order, covariant returns, default method conflicts |
| Java 17 features | records, sealed classes, pattern matching for instanceof, switch expressions | record constructor rules, permits, final/sealed/non-sealed, pattern variable scope |
| Exceptions | checked vs unchecked, try-with-resources, suppressed exceptions | close order, multi-catch rules, overriding with checked exceptions |
| Generics and collections | wildcards, List/Set/Map/Queue, comparators | type erasure, raw types, immutable factories, TreeSet/TreeMap ordering |
| Lambdas and streams | functional interfaces, pipelines, collectors, Optional | lazy intermediate ops, stream reuse, orElse eagerness, parallel stream side effects |
| Date/time/localization | java.time, Locale, formatters, resource bundles | immutable date/time types, Period vs Duration, bundle lookup order |
| I/O and NIO.2 | Path, Files, byte/char streams, serialization | lexical vs real path operations, lazy file streams, transient/static serialization |
| Concurrency | threads, executors, futures, synchronization, atomics | start() vs run(), visibility vs atomicity, deadlock, non-thread-safe collections |
| Modules | module-info.java, requires, exports, opens, services | readability vs accessibility, class path vs module path, automatic/unnamed modules |
| JDBC | Connection, PreparedStatement, ResultSet, transactions | 1-based parameters, cursor position, auto-commit, resource closing |
Core Language Rules
Declarations, Scope, and var
| Feature | Rule | Exam reminder |
|---|
| Local variable scope | Begins at declaration and ends at enclosing block | A variable is not in scope before its declaration |
| Instance field default | Numeric 0, boolean false, object refs null | Local variables have no default; must be definitely assigned |
var | Local variable type inference at compile time | Not dynamic typing |
var requires initializer | var x = 10; valid | var x;, var x = null;, var a = {1,2}; invalid |
var locations | Local variables and lambda parameters | Not fields, method return types, formal method parameters, catch parameters |
Lambda var | If one lambda parameter uses var, all explicit parameters must use var | (var a, var b) -> a + b valid; (var a, b) -> ... invalid |
| Shadowing | Inner declarations may shadow fields | Local variables cannot be redeclared in the same scope |
| Effectively final | Required for captured local variables | Variable must not be reassigned after capture |
var names = List.of("Ana", "Bo"); // inferred List<String>
var nums = new int[] {1, 2, 3}; // valid
// var bad = {1, 2, 3}; // invalid
// var none = null; // invalid
int count = 0;
// Runnable r = () -> count++; // invalid: count not effectively final
| Topic | Rule |
|---|
| Integer literal default | int unless suffixed with L/l |
| Floating literal default | double unless suffixed with F/f |
| Underscores in literals | Allowed between digits only |
char | Unsigned 16-bit UTF-16 code unit; participates in numeric promotion |
| Arithmetic promotion | byte, short, and char promote to int before arithmetic |
| Binary numeric promotion | If either operand is double, result double; else float; else long; else int |
| Compound assignment | Includes implicit narrowing cast |
| Constant narrowing | Compile-time constants in range may assign to byte, short, char |
byte b = 10;
// b = b + 1; // invalid: b + 1 is int
b += 1; // valid: implicit cast to byte
short s = 1;
char c = 2;
int result = s + c; // promoted to int
long x = 10; // int literal widened to long
float f = 10.0f; // suffix required for float literal
Operators and Evaluation
| Operator area | Key rules |
|---|
&&, ` | |
&, ` | , ^` |
== with primitives | Compares values after promotion |
== with references | Compares object identity |
| Mixed wrapper/primitive | Wrapper is unboxed |
| Assignment expressions | Return assigned value |
Ternary ?: | May trigger numeric promotion or boxing/unboxing |
| Pre/post increment | Prefix changes before value use; postfix changes after value use |
Integer a = 1000;
Integer b = 1000;
System.out.println(a == b); // false: different references likely
System.out.println(a.equals(b)); // true
Integer c = 10;
int d = 10;
System.out.println(c == d); // true: c unboxed
Wrapper cache details can appear in questions, but the safer exam habit is: use equals() for value equality unless the question is specifically testing identity or unboxing.
Control Flow and Pattern Matching
if, Loops, Labels, and break/continue
| Construct | Rule |
|---|
if condition | Must be boolean, not numeric |
while / do while | Condition must be boolean |
Enhanced for | Works with arrays and Iterable |
break label | Exits the labeled statement |
continue label | Continues the labeled loop |
| Unreachable code | Compile-time error, except some special cases after non-constant conditions |
outer:
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (j == 1) continue outer;
}
}
Switch Statements and Switch Expressions
| Feature | Switch statement | Switch expression |
|---|
| Produces value | No | Yes |
| Fall-through | Possible with colon labels | Not with arrow labels |
| Exhaustiveness | Not generally required | Required |
yield | Not used | Used to return a value from block cases |
| Case labels | Compatible constants, enum constants, strings, etc. | Same core idea |
default | Optional for statement | Usually needed unless exhaustive |
int score = 2;
String grade = switch (score) {
case 1 -> "low";
case 2, 3 -> "mid";
default -> {
String label = "high";
yield label;
}
};
Pattern Matching for instanceof
| Pattern | Rule |
|---|
obj instanceof String s | If true, s is a String pattern variable |
| Scope | Pattern variable is available where definitely matched |
&& | Pattern variable available on right side |
| ` | |
Object obj = "java";
if (obj instanceof String s && s.length() > 2) {
System.out.println(s.toUpperCase());
}
// if (obj instanceof String t || t.length() > 2) { } // invalid
Strings, Text Blocks, Arrays, and Formatting
String and StringBuilder
| Type/API | Key facts |
|---|
String | Immutable; methods return new strings |
| String literals | Interned |
StringBuilder | Mutable, not synchronized, does not override equals() |
StringBuffer | Mutable and synchronized |
substring | End index exclusive |
replace | Replaces all matching chars or sequences |
strip | Unicode-aware whitespace removal |
trim | Removes characters <= '\u0020' |
String.format | Uses format specifiers and optional locale |
| Text blocks | Multi-line strings using """; incidental indentation handled |
String s = "abc";
s.concat("d");
System.out.println(s); // abc
StringBuilder sb = new StringBuilder("abc");
sb.append("d");
System.out.println(sb); // abcd
String text = """
line one
line two
""";
Arrays
| Topic | Rule |
|---|
| Declaration | int[] a preferred; int a[] valid |
| Initialization | new int[3] gives default values |
| Anonymous array | new int[] {1, 2, 3} |
| Length | Array field length, not method |
| Multidimensional arrays | Arrays of arrays; rows may be different lengths |
| Covariance | String[] is an Object[], but unsafe stores fail at runtime |
| Sorting/searching | Arrays.sort, Arrays.binarySearch |
| Comparison | Arrays.compare, Arrays.mismatch, Arrays.equals |
Object[] values = new String[2];
// values[0] = new Object(); // ArrayStoreException at runtime
int[][] grid = new int[2][];
grid[0] = new int[] {1, 2};
grid[1] = new int[] {3};
Object-Oriented Java
Access Modifiers
| Modifier | Same class | Same package | Subclass different package | Other package |
|---|
private | Yes | No | No | No |
| package-private | Yes | Yes | No | No |
protected | Yes | Yes | Yes, through inheritance rules | No general access |
public | Yes | Yes | Yes | Yes |
High-yield rules:
- Top-level classes can be
public or package-private only. - A source file may contain multiple top-level classes, but at most one public top-level class.
- The public top-level class name must match the file name.
protected across packages is not the same as package access; access must be through the subclass relationship.
Initialization Order
| Order | What runs |
|---|
| 1 | Static fields and static initializers of superclass |
| 2 | Static fields and static initializers of subclass |
| 3 | Instance fields and instance initializers of superclass |
| 4 | Superclass constructor |
| 5 | Instance fields and instance initializers of subclass |
| 6 | Subclass constructor |
class Parent {
static { System.out.print("A"); }
{ System.out.print("B"); }
Parent() { System.out.print("C"); }
}
class Child extends Parent {
static { System.out.print("D"); }
{ System.out.print("E"); }
Child() { System.out.print("F"); }
}
// new Child() after class loading prints: A D B C E F
Inheritance, Overriding, and Hiding
| Concept | Rule |
|---|
| Overriding | Instance method in subclass replaces inherited instance method |
| Static method hiding | Static methods are hidden, not overridden |
| Field hiding | Fields are hidden, not overridden |
| Access on override | Cannot reduce visibility |
| Return type | May be covariant |
| Checked exceptions | Override cannot throw broader checked exceptions |
final method | Cannot be overridden |
final class | Cannot be extended |
abstract class | Cannot be instantiated; may have constructors |
| Constructor | Not inherited; first statement is this(...) or super(...) |
class A {
static void s() { System.out.print("A.s "); }
void m() { System.out.print("A.m "); }
}
class B extends A {
static void s() { System.out.print("B.s "); }
@Override void m() { System.out.print("B.m "); }
}
A ref = new B();
ref.s(); // A.s: static method chosen by reference type
ref.m(); // B.m: instance method chosen by object type
Interfaces
| Interface member | Implicit modifiers / rules |
|---|
| Field | public static final |
| Abstract method | public abstract |
| Default method | Instance method with body; inherited by implementers |
| Static method | Called using interface name |
| Private method | Helper for default/static methods |
| Private static method | Static helper |
| Constructor | Interfaces do not have constructors |
Default method conflict rules:
- Class method wins over interface default.
- More specific interface wins over less specific interface.
- If unrelated defaults conflict, implementing class must override.
interface A {
default String name() { return "A"; }
}
interface B {
default String name() { return "B"; }
}
class C implements A, B {
public String name() {
return A.super.name();
}
}
Records
| Record feature | Rule |
|---|
| Purpose | Transparent, shallowly immutable data carrier |
| Declaration | record Point(int x, int y) {} |
| Superclass | Implicitly extends java.lang.Record; cannot extend another class |
| Finality | Records are implicitly final |
| Components | Private final fields plus public accessor methods named after components |
| Generated methods | Constructor, accessors, equals, hashCode, toString |
| Interfaces | Records may implement interfaces |
| Extra fields | Static fields allowed; additional instance fields not allowed |
| Compact constructor | No parameter list; validates or normalizes component parameters |
| Canonical constructor | Parameter list matches record components |
record Range(int start, int end) {
Range {
if (end < start) throw new IllegalArgumentException();
}
int length() {
return end - start;
}
}
Record traps:
- Accessor is
x(), not getX(), unless manually added. - Compact constructors assign component fields automatically after the body.
- You may reassign constructor parameters in a compact constructor to normalize values.
- Records are shallowly immutable; mutable component objects can still mutate internally.
Sealed Classes and Interfaces
| Modifier | Meaning |
|---|
sealed | Restricts direct subclasses/implementers |
permits | Lists permitted direct subclasses, unless inferable in same source context |
final subclass | Cannot be extended further |
sealed subclass | Continues restriction |
non-sealed subclass | Reopens hierarchy for further extension |
sealed interface Shape permits Circle, Rectangle {}
final class Circle implements Shape {}
non-sealed class Rectangle implements Shape {}
class Square extends Rectangle {} // allowed because Rectangle is non-sealed
Exam reminders:
- Every direct subclass of a sealed type must declare exactly one of
final, sealed, or non-sealed. - Sealing controls direct inheritance, not object creation by itself.
- A sealed class can be abstract or concrete.
Enums
| Enum rule | Detail |
|---|
| Constants | Listed first; semicolon needed if members follow |
| Constructor | Implicitly private |
| Superclass | Extends java.lang.Enum; cannot extend another class |
| Interfaces | Enums may implement interfaces |
| Methods | May define fields, constructors, methods, abstract methods |
| Per-constant body | Constants can override methods |
| Common APIs | values(), valueOf(String), name(), ordinal() |
enum Level {
LOW(1), HIGH(2);
private final int code;
Level(int code) {
this.code = code;
}
int code() {
return code;
}
}
Exceptions and Resource Management
Exception Type Rules
| Type | Checked? | Must handle or declare? |
|---|
Exception excluding RuntimeException subclasses | Yes | Yes |
RuntimeException and subclasses | No | No |
Error and subclasses | No | No |
| Custom checked exception | Extends Exception but not RuntimeException | Yes |
| Custom unchecked exception | Extends RuntimeException | No |
Try, Catch, Finally, and Multi-Catch
| Feature | Rule |
|---|
| Catch order | More specific before more general |
| Multi-catch | Alternatives cannot be related by subclassing |
| Multi-catch variable | Effectively final |
finally | Runs after try/catch unless abnormal VM termination |
Return in finally | Can override previous return or thrown exception; usually a trap |
| Override exceptions | Cannot broaden checked exceptions |
try {
throw new java.io.IOException();
} catch (java.io.FileNotFoundException e) {
// more specific first
} catch (java.io.IOException | RuntimeException e) {
// e is effectively final
}
Try-With-Resources
| Rule | Exam detail |
|---|
| Resource type | Must implement AutoCloseable or Closeable |
| Close order | Reverse order of declaration |
| Suppressed exceptions | Exceptions from close() are suppressed if try block already threw |
| Effectively final resources | Existing effectively final variables can be used |
catch/finally | Optional |
try (var in = new FileInputStream("a.txt");
var out = new FileOutputStream("b.txt")) {
in.transferTo(out);
} // out closes first, then in
Generics and Collections
Generics Essentials
| Concept | Rule |
|---|
| Type erasure | Generic type parameters are mostly removed at runtime |
| Invariance | List<String> is not a subtype of List<Object> |
| Raw type | Disables generic checks; may cause heap pollution |
| Generic method | Type parameter before return type |
| Diamond operator | Infers type arguments from context |
| Bounded type | <T extends Number> |
| Multiple bounds | Class bound first, then interfaces |
| Cannot create | new T(), new T[], new List<String>[] |
| Cannot test | obj instanceof List<String> |
static <T extends Comparable<T>> T max(T a, T b) {
return a.compareTo(b) >= 0 ? a : b;
}
Wildcards: PECS
| Need | Use | Example |
|---|
| Read values produced by collection | ? extends T | List<? extends Number> |
| Write values consumed by collection | ? super T | List<? super Integer> |
| Exact read/write of T | List<T> | Generic method |
| Unknown type | ? | List<?> |
List<? extends Number> nums = List.of(1, 2, 3);
Number n = nums.get(0);
// nums.add(4); // invalid except null
List<? super Integer> sink = new ArrayList<Number>();
sink.add(10);
Object value = sink.get(0);
Collection Selection Matrix
| Need | Choose | Notes |
|---|
| Ordered sequence with duplicates | ArrayList | Fast random access |
| Frequent insert/remove at ends | ArrayDeque | Often preferred over Stack/LinkedList for stack/queue behavior |
| Unique elements, no guaranteed order | HashSet | Uses hashCode and equals |
| Unique sorted elements | TreeSet | Requires natural ordering or comparator |
| Unique insertion order | LinkedHashSet | Predictable iteration |
| Key-value lookup | HashMap | Map is not a Collection |
| Sorted key-value lookup | TreeMap | Sorted by key |
| Insertion-order map | LinkedHashMap | Predictable iteration |
| Thread-safe high-concurrency map | ConcurrentHashMap | Does not allow null keys or null values |
| Read-heavy thread-safe list | CopyOnWriteArrayList | Writes copy underlying array |
Factory and Wrapper Methods
| API | Result | Trap |
|---|
List.of(...) | Unmodifiable list | Rejects null |
Set.of(...) | Unmodifiable set | Rejects null and duplicates |
Map.of(...) | Unmodifiable map | Rejects null and duplicate keys |
List.copyOf(...) | Unmodifiable copy | Rejects null |
Arrays.asList(array) | Fixed-size list backed by array | set allowed; add/remove not allowed |
Collections.unmodifiableList(list) | Unmodifiable view | Underlying list changes are visible |
Collections.sort(list) | Sorts mutable list in place | Needs comparable elements or comparator |
Comparator and Comparable
| API | Purpose |
|---|
Comparable<T> | Natural ordering via compareTo |
Comparator<T> | External ordering via compare |
Comparator.comparing | Build comparator from key extractor |
thenComparing | Tie-breaker |
reversed | Reverse order |
nullsFirst / nullsLast | Handle null values |
record Person(String name, int age) {}
var people = new ArrayList<Person>();
people.sort(
Comparator.comparing(Person::name)
.thenComparingInt(Person::age)
);
equals, hashCode, and ordering traps:
- If two objects are equal by
equals, they must have the same hashCode. HashSet uniqueness uses equals and hashCode.TreeSet uniqueness is based on comparison result 0.- Natural ordering inconsistent with
equals can produce surprising set/map behavior.
Lambdas and Functional Interfaces
Built-In Functional Interfaces
| Interface | Abstract method | Input | Output |
|---|
Predicate<T> | test | T | boolean |
Consumer<T> | accept | T | void |
Supplier<T> | get | none | T |
Function<T,R> | apply | T | R |
UnaryOperator<T> | apply | T | T |
BinaryOperator<T> | apply | T, T | T |
BiPredicate<T,U> | test | T, U | boolean |
BiConsumer<T,U> | accept | T, U | void |
BiFunction<T,U,R> | apply | T, U | R |
Runnable | run | none | void |
Callable<V> | call | none | V, may throw checked exception |
Comparator<T> | compare | T, T | int |
Lambda Syntax and Method References
| Form | Example |
|---|
| Inferred parameter | x -> x.length() |
| Explicit parameter type | (String x) -> x.length() |
| Multiple parameters | (a, b) -> a + b |
| Block body | x -> { return x.length(); } |
| Static method reference | Integer::parseInt |
| Bound instance reference | System.out::println |
| Unbound instance reference | String::length |
| Constructor reference | ArrayList::new |
Predicate<String> nonEmpty = s -> !s.isEmpty();
Function<String, Integer> parse = Integer::parseInt;
Supplier<List<String>> makeList = ArrayList::new;
Lambda traps:
- A lambda targets a functional interface, not just any type.
- Checked exceptions must match the functional interface method.
this inside a lambda refers to the enclosing instance.- Captured local variables must be final or effectively final.
- Parameter names cannot redeclare local variables already in scope.
Streams and Optionals
Stream Pipeline Rules
| Pipeline part | Examples | Notes |
|---|
| Source | collection, array, generator, file lines | Creates stream |
| Intermediate operation | filter, map, sorted, distinct, peek, limit, skip | Lazy; returns stream |
| Terminal operation | forEach, collect, reduce, count, findFirst, anyMatch | Triggers processing; stream consumed |
| Stateless operation | filter, map | Independent per element |
| Stateful operation | sorted, distinct, limit, skip | May need more elements/state |
| Short-circuiting | limit, findFirst, findAny, anyMatch, allMatch, noneMatch | May stop early |
long count = List.of("a", "bb", "ccc").stream()
.filter(s -> s.length() > 1)
.map(String::toUpperCase)
.count();
Stream traps:
- A stream cannot be reused after a terminal operation.
- Intermediate operations do not run until a terminal operation occurs.
- Avoid modifying the stream source during pipeline execution.
peek is mainly for debugging; do not rely on it for required side effects.- Parallel stream operations should be stateless, non-interfering, and associative where reduction is involved.
Common Stream Operations
| Operation | Type | Purpose |
|---|
filter(Predicate) | Intermediate | Keep matching elements |
map(Function) | Intermediate | Transform one-to-one |
flatMap(Function) | Intermediate | Transform one-to-many and flatten |
distinct() | Intermediate | Remove duplicates by equals |
sorted() | Intermediate | Natural sort |
sorted(Comparator) | Intermediate | Custom sort |
limit(n) | Intermediate | First n elements |
skip(n) | Intermediate | Drop first n elements |
takeWhile | Intermediate | Take until predicate becomes false |
dropWhile | Intermediate | Drop until predicate becomes false |
forEach | Terminal | Apply action, order not guaranteed in parallel |
forEachOrdered | Terminal | Preserve encounter order where defined |
collect | Terminal | Mutable reduction |
reduce | Terminal | Immutable reduction |
toList() | Terminal | Returns an unmodifiable list in modern Java |
count | Terminal | Number of elements |
min / max | Terminal | Optional result |
findFirst | Terminal | First by encounter order |
findAny | Terminal | Any element, useful in parallel |
Primitive Streams
| Stream | Common methods |
|---|
IntStream | range, rangeClosed, sum, average, mapToObj, boxed |
LongStream | range, rangeClosed, sum, average, boxed |
DoubleStream | sum, average, boxed |
int total = IntStream.rangeClosed(1, 5).sum(); // 15
List<Integer> boxed = IntStream.range(1, 4).boxed().toList();
Collectors
| Collector | Result |
|---|
Collectors.toList() | Mutable list implementation not guaranteed |
Collectors.toSet() | Set implementation not guaranteed |
Collectors.toMap(k, v) | Map; duplicate keys throw unless merge function supplied |
Collectors.groupingBy(classifier) | Map<K, List<T>> by classifier |
Collectors.partitioningBy(predicate) | Map<Boolean, List<T>> |
Collectors.joining(delimiter) | Concatenated string |
Collectors.counting() | Count as Long |
Collectors.mapping(...) | Downstream mapping |
Collectors.filtering(...) | Downstream filtering |
Collectors.reducing(...) | Downstream reduction |
Map<Integer, List<String>> byLength =
Stream.of("a", "bb", "cc")
.collect(Collectors.groupingBy(String::length));
Map<Character, String> merged =
Stream.of("ant", "ape")
.collect(Collectors.toMap(
s -> s.charAt(0),
s -> s,
(left, right) -> left + "," + right
));
Optional
| Method | Behavior |
|---|
of(value) | Throws if value is null |
ofNullable(value) | Empty if value is null |
empty() | Empty optional |
get() | Returns value or throws if empty |
isPresent / isEmpty | Presence tests |
ifPresent | Run consumer when value exists |
orElse(value) | Eagerly evaluates fallback argument |
orElseGet(supplier) | Lazily calls supplier only if empty |
orElseThrow() | Throws if empty |
map | Transform contained value |
flatMap | Transform to another optional without nesting |
filter | Keep value only if predicate matches |
String value = Optional.of("java")
.filter(s -> s.length() > 2)
.map(String::toUpperCase)
.orElse("NONE");
Dates, Times, and Localization
java.time Selection Table
| Need | Type |
|---|
| Date without time or zone | LocalDate |
| Time without date or zone | LocalTime |
| Date and time without zone | LocalDateTime |
| Date and time with zone | ZonedDateTime |
| Machine timestamp | Instant |
| Time zone identifier | ZoneId |
| Zone offset | ZoneOffset |
| Date-based amount | Period |
| Time-based amount | Duration |
| Month/day recurring date | MonthDay |
| Year/month recurring date | YearMonth |
LocalDate date = LocalDate.of(2026, Month.JUNE, 18);
LocalDate next = date.plus(Period.ofDays(3));
LocalTime time = LocalTime.of(9, 30);
LocalTime later = time.plus(Duration.ofMinutes(45));
High-yield traps:
java.time classes are immutable.LocalDate does not contain time or zone information.- Use
Period for date-based units; use Duration for time-based units. - Month numbers are 1-based in factory methods.
- Many date/time methods throw runtime exceptions for invalid dates or unsupported units.
| API | Purpose |
|---|
DateTimeFormatter.ISO_LOCAL_DATE | Standard ISO local date |
DateTimeFormatter.ofPattern | Custom pattern |
format | Temporal object to text |
parse | Text to temporal object |
NumberFormat.getCurrencyInstance(locale) | Localized currency |
NumberFormat.getPercentInstance(locale) | Localized percent |
CompactNumberFormat via NumberFormat.getCompactNumberInstance | Localized compact numbers |
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd");
String text = LocalDate.of(2026, 6, 18).format(fmt);
LocalDate parsed = LocalDate.parse(text, fmt);
Locale and Resource Bundles
| Concept | Rule |
|---|
Locale | Language, country/region, optional variant/extensions |
| Builder | new Locale.Builder().setLanguage("en").setRegion("US").build() |
| Resource bundle | Loads localized resources by base name and locale |
| Properties bundle | Key-value .properties files |
| Class bundle | Java class extending ListResourceBundle |
| Missing key | Throws MissingResourceException |
Resource bundle search conceptually moves from most specific to less specific, then may consider default locale, then base bundle. For example, for base messages and locale fr_CA, candidates should recognize names such as:
messages_fr_CA
messages_fr
messages
I/O, NIO.2, and Serialization
Stream and Reader/Writer Selection
| Need | Use |
|---|
| Binary input | InputStream |
| Binary output | OutputStream |
| Character input | Reader |
| Character output | Writer |
| Buffered binary input | BufferedInputStream |
| Buffered character input | BufferedReader |
| Object serialization | ObjectInputStream, ObjectOutputStream |
| Filesystem utilities | Files |
| Path abstraction | Path |
try (BufferedReader reader = Files.newBufferedReader(Path.of("data.txt"))) {
reader.lines()
.filter(s -> !s.isBlank())
.forEach(System.out::println);
}
Path and Files
| API | Key point |
|---|
Path.of(...) | Creates path object |
getFileName | Last name element |
getParent | Parent path or null |
getRoot | Root component or null |
isAbsolute | Whether path is absolute |
toAbsolutePath | Converts to absolute path; does not require file to exist |
normalize | Removes redundant . and .. lexically |
toRealPath | Requires file to exist; resolves real path |
resolve | Combine paths |
relativize | Path from one path to another; paths must be compatible |
Files.exists | Checks existence; result may be affected by permissions |
Files.isSameFile | Compares actual files |
Files.copy | Copy file/stream |
Files.move | Move or rename |
Files.delete | Throws if deletion fails |
Files.deleteIfExists | No exception if missing |
Files.walk / find / list | Return lazy streams; use try-with-resources |
Path p = Path.of("logs", ".", "app.log").normalize();
Path absolute = p.toAbsolutePath();
try (Stream<Path> paths = Files.walk(Path.of("src"))) {
paths.filter(Files::isRegularFile)
.forEach(System.out::println);
}
NIO.2 traps:
- Many
Path methods are lexical and do not access the filesystem. Files.walk, Files.find, and Files.list must be closed.Path iteration skips the root and iterates name elements.resolve with an absolute right-hand path returns the right-hand path.
Serialization
| Feature | Rule |
|---|
| Serializable class | Implements java.io.Serializable marker interface |
transient field | Not serialized |
| Static field | Not part of serialized object state |
serialVersionUID | Version identifier field |
| Serializable superclass | Its object state is serialized |
| Non-serializable superclass | No-arg constructor runs during deserialization |
| Serializable class constructor | Does not run during deserialization |
| Custom hooks | Private writeObject / readObject methods |
class User implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private transient String sessionToken;
}
Concurrency
Thread Basics
| Concept | Rule |
|---|
Thread.start() | Starts a new thread and calls run() asynchronously |
Thread.run() | Normal method call if invoked directly |
| Restarting thread | Calling start() twice on same thread throws runtime exception |
Runnable | No return value, no checked exception from run |
Callable<V> | Returns value and may throw checked exception |
sleep | Static method; pauses current thread |
interrupt | Requests interruption; blocking methods may throw InterruptedException |
| Daemon thread | Does not prevent JVM exit |
Runnable task = () -> System.out.println(Thread.currentThread().getName());
Thread t = new Thread(task);
t.start();
Executors and Futures
| API | Purpose |
|---|
Executor | Executes Runnable |
ExecutorService | Manages lifecycle and task submission |
submit | Returns Future |
execute | No result returned |
Future.get | Blocks; wraps task exceptions |
invokeAll | Runs collection of tasks; returns futures |
invokeAny | Returns one successful result |
shutdown | Stops accepting new tasks; existing tasks continue |
shutdownNow | Attempts to stop running tasks and returns pending tasks |
ScheduledExecutorService | Delayed or periodic execution |
ExecutorService service = Executors.newFixedThreadPool(2);
try {
Future<Integer> future = service.submit(() -> 40 + 2);
Integer answer = future.get();
} finally {
service.shutdown();
}
Synchronization, Visibility, and Atomicity
| Tool | Use | Trap |
|---|
synchronized method/block | Mutual exclusion using monitor | Must use same lock object |
wait / notify / notifyAll | Coordination through monitor | Must own monitor; usually in loop |
volatile | Visibility guarantee for reads/writes | Does not make compound actions atomic |
AtomicInteger etc. | Lock-free atomic operations | Operations are atomic per method call |
ReentrantLock | Explicit lock/unlock | Use finally to unlock |
| Concurrent collections | Thread-safe collection operations | Iteration semantics differ |
| Parallel streams | Data parallelism | Avoid shared mutable state |
class Counter {
private final AtomicInteger value = new AtomicInteger();
int increment() {
return value.incrementAndGet();
}
}
Deadlock checklist:
- Are two locks acquired in different orders?
- Is a lock held while waiting for another lock?
- Is external code called while holding a lock?
- Is
wait() used without a condition loop?
module-info.java Directives
| Directive | Meaning |
|---|
requires module.name; | Current module reads another module |
requires transitive module.name; | Dependents also read the required module |
requires static module.name; | Required at compile time, optional at runtime |
exports package.name; | Public types in package accessible to other modules |
exports package.name to module.name; | Qualified export |
opens package.name; | Allows deep reflection at runtime |
opens package.name to module.name; | Qualified open |
open module name {} | Opens all packages for deep reflection |
uses service.Interface; | Declares service consumption |
provides service.Interface with impl.Class; | Declares service provider |
java.base | Required implicitly by every module |
module com.example.app {
requires java.sql;
requires transitive com.example.api;
exports com.example.app.api;
opens com.example.app.model;
uses com.example.spi.Plugin;
provides com.example.spi.Plugin with com.example.impl.DefaultPlugin;
}
Module Decision Points
| Question | Exam answer pattern |
|---|
| Need compile-time and runtime access to public exported API? | requires plus provider module must exports package |
| Need clients of your module to read your dependency automatically? | requires transitive |
| Need reflection into non-public members at runtime? | opens, not just exports |
| Need restrict export to selected modules? | Qualified exports ... to ... |
| Need service loading? | Consumer uses uses; provider uses provides ... with ... |
| Need all packages open for reflection? | open module |
| On class path? | Code is in unnamed module |
| Plain JAR on module path? | Automatic module |
Module traps:
- Readability and accessibility are separate:
requires grants readability; exports grants access to public types in a package. - Packages are not exported by default.
- Reflection into non-public members requires openness.
- Named modules cannot generally depend on classes from the unnamed module.
- Automatic modules export all packages and read other resolved modules.
- Avoid split packages across named modules.
Useful Module Commands
javac -d mods --module-source-path src $(find src -name "*.java")
java --module-path mods \
--module com.example.app/com.example.app.Main
jar --create --file app.jar \
--main-class com.example.app.Main \
-C mods/com.example.app .
jdeps --module-path mods --module com.example.app
JDBC
Core JDBC Objects
| Object | Purpose |
|---|
DriverManager | Gets connections using JDBC URL |
DataSource | Connection factory, often preferred in managed environments |
Connection | Database session; transactions |
Statement | Executes static SQL |
PreparedStatement | Precompiled SQL with parameters |
CallableStatement | Stored procedures |
ResultSet | Cursor over query results |
SQLException | JDBC checked exception |
SQLWarning | Non-fatal database warning |
Statement Execution
| Method | Use |
|---|
executeQuery | SQL returning a ResultSet, typically SELECT |
executeUpdate | DML/DDL returning update count |
execute | Unknown or mixed result type |
getResultSet | Retrieve result set after execute |
getUpdateCount | Retrieve update count after execute |
String sql = "select id, name from users where status = ?";
try (Connection conn = DriverManager.getConnection(url);
PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setString(1, "ACTIVE"); // JDBC parameters are 1-based
try (ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
int id = rs.getInt("id");
String name = rs.getString("name");
}
}
}
ResultSet and Transactions
| Topic | Rule |
|---|
| Cursor position | Initially before first row |
next() | Moves cursor and returns whether row exists |
| Column indexes | 1-based |
| Column labels | Often clearer than indexes |
getInt on SQL NULL | Returns 0; call wasNull() to distinguish |
| Auto-commit | Usually enabled by default |
| Manual transaction | setAutoCommit(false), then commit or rollback |
| Savepoint | Partial rollback marker |
| Closing resources | Close ResultSet, Statement, Connection; try-with-resources preferred |
try (Connection conn = DriverManager.getConnection(url)) {
conn.setAutoCommit(false);
try (PreparedStatement ps = conn.prepareStatement(
"update account set balance = balance - ? where id = ?")) {
ps.setBigDecimal(1, amount);
ps.setLong(2, accountId);
ps.executeUpdate();
conn.commit();
} catch (SQLException e) {
conn.rollback();
throw e;
}
}
Annotations
| Annotation | Purpose |
|---|
@Override | Compile-time check that a method overrides or implements |
@Deprecated | Marks API as discouraged |
@SuppressWarnings | Suppresses compiler warnings |
@FunctionalInterface | Confirms interface has one abstract method |
@SafeVarargs | Suppresses heap pollution warnings for safe varargs usage |
@Retention | Controls annotation availability: SOURCE, CLASS, RUNTIME |
@Target | Controls legal annotation locations |
@Repeatable | Allows repeated annotation of same type |
@Inherited | Class-level annotation inheritance only |
@Documented | Included in generated documentation |
Annotation element rules:
- Element types may be primitives,
String, Class, enum, annotation, or arrays of those. - Element defaults must be compile-time constants where applicable.
- If the only required element is named
value, the name may be omitted.
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@interface Reviewed {
String value();
int version() default 1;
}
@Reviewed("exam")
class Service {}
Final Exam-Prep Checklist
Compilation and Syntax Traps
- Check whether code fails at compile time before reasoning about runtime output.
- Verify imports, access modifiers, checked exceptions, and generic type compatibility.
- Watch for local variables that are not definitely assigned.
- Remember that
var is compile-time inference, not runtime typing. - Distinguish overloaded method selection at compile time from overridden method dispatch at runtime.
- Check whether a lambda target type permits checked exceptions.
- Confirm whether a stream has a terminal operation and whether it is reused.
API Behavior Traps
String, LocalDate, LocalTime, LocalDateTime, and most java.time types are immutable.StringBuilder.equals() uses object identity unless comparing same reference.List.of, Set.of, and Map.of are unmodifiable and reject null.Arrays.asList is fixed-size and backed by the array.TreeSet and TreeMap need consistent ordering.Optional.orElse evaluates its argument eagerly; orElseGet is lazy.Files.walk, Files.find, and Files.list return streams that should be closed.PreparedStatement parameters and ResultSet column indexes are 1-based.volatile improves visibility, not compound atomicity.exports is for API access; opens is for deep reflection.
Practical Next Step
Use this Quick Reference as a checklist while working timed Oracle Java SE 17 Developer (1Z0-829) practice questions. For every missed item, classify the miss as syntax, API behavior, inheritance/dispatch, generics, stream pipeline, concurrency, modules, or JDBC, then drill that category with small compilable code examples.