Exam identity and use
This independent Quick Reference supports preparation for Oracle Java SE 21 Developer Professional (1Z0-830). Use it as a compact checklist for language rules, core APIs, Java 21 features, common traps, and decision points that are easy to miss under exam timing.
Unless a question explicitly states that preview features are enabled, answer using standard Java SE 21 features only. Java 21 includes preview/incubator features, but exam-safe reasoning should not assume them.
High-yield topic map
| Area | Know cold | Common trap |
|---|
| Core language | numeric promotion, var, initialization order, access control, overloading/overriding | Overload chosen at compile time; override dispatched at runtime |
| OOP | interfaces, abstract classes, nested classes, enums, sealed types, records | Static methods are hidden, not overridden |
| Java 21 patterns | pattern matching for switch, record patterns, guarded patterns | Pattern dominance and null handling |
| Collections/generics | PECS, erasure, ordering, equality, mutability, sequenced collections | List<?> is not a list you can add real elements to |
| Lambdas/streams | functional interfaces, method refs, lazy pipelines, collectors, Optional | orElse() evaluates eagerly; streams are single-use |
| Exceptions | checked vs unchecked, multi-catch, try-with-resources, suppressed exceptions | Catch order: specific before general |
| Modules | requires, exports, opens, services, class path vs module path | Public class is inaccessible outside module unless package is exported |
| Concurrency | executors, futures, synchronization, atomics, concurrent collections, virtual threads | volatile gives visibility, not compound atomicity |
| I/O and NIO.2 | Path, Files, streams/readers/writers, resource closing | normalize() is syntactic; toRealPath() checks the file system |
| JDBC | Connection, PreparedStatement, ResultSet, transactions | JDBC indexes are 1-based |
| Localization/time | Locale, ResourceBundle, DateTimeFormatter, Period, Duration | MM is month; mm is minute |
| Secure coding | immutability, input validation, SQL injection, path traversal | Do not expose mutable internals from records/classes |
Compilation, execution, packages, and modules
Class path vs module path
| Concept | Class path | Module path |
|---|
| Code location | Unnamed module | Named modules and automatic modules |
| Dependency model | All visible classes searched by package/name | Module must read another module |
| Encapsulation | Package/public only | Module exports control external access |
| Non-modular JAR | Normal class path entry | Automatic module with inferred name |
| Split packages | Often tolerated on class path | Problematic/invalid across resolved modules |
| Main run style | java -cp ... pkg.Main | java -p ... -m module/pkg.Main |
## Compile a modular application
javac --module-source-path src -d mods -m com.example.app
## Run a modular application
java --module-path mods -m com.example.app/com.example.app.Main
## Describe a modular JAR
jar --describe-module --file app.jar
Module directives
| Directive | Meaning | Exam use |
|---|
requires m; | Current module depends on m | Needed to compile against exported packages of m |
requires transitive m; | Re-export dependency to downstream modules | API module exposes types from another module |
requires static m; | Needed at compile time, optional at run time | Compile-only annotations or optional tooling |
exports p; | Public types in package p accessible to all reading modules | Normal API exposure |
exports p to m; | Qualified export | API visible only to named module(s) |
opens p; | Allows deep reflection at run time | Frameworks, serialization, dependency injection |
opens p to m; | Qualified reflective access | Safer than opening to everyone |
uses S; | Consumes service interface S | With ServiceLoader |
provides S with Impl; | Registers implementation | Provider module declaration |
open module m {} | Opens all packages reflectively | Does not export all packages for compilation |
module com.example.app {
requires java.sql;
requires transitive com.example.api;
exports com.example.app.api;
opens com.example.app.model to com.fasterxml.jackson.databind;
uses com.example.spi.Reporter;
}
Module traps
| Trap | Correct rule |
|---|
public class is always accessible | Outside a named module, the package must also be exported |
opens is the same as exports | opens is for deep reflection; exports is for compile-time/public access |
| Named modules can depend on class path code | Named modules cannot read the unnamed module |
requires transitive is always better | Use it only when your exported API exposes the dependency |
| Service provider must be exported | Provider package need not be exported just to be loaded as a service |
| Cyclic module dependencies are fine | Module dependency cycles are not allowed |
Core Java language rules
Declarations, access, and initialization
| Rule | Remember |
|---|
| Top-level type access | public or package-private only |
| Source file name | Must match the public top-level class/interface/record/enum name |
| Initialization order | Superclass static, subclass static, superclass instance, superclass constructor, subclass instance, subclass constructor |
| Static members | Belong to class; can be hidden, not overridden |
| Instance initialization blocks | Run before constructor body, after super() |
final variable | Must be assigned exactly once before use |
protected outside package | Accessible through this, super, or a reference of the subclass type, not arbitrary superclass instances |
| Garbage collection | Eligibility is based on reachability; System.gc() is only a request |
var quick rules
| Valid | Invalid / trap |
|---|
| Local variables with initializer | Fields, method parameters, method return types |
Enhanced for variables | var x; with no initializer |
Lambda parameters when all explicit parameters use var | Mixing var and explicit/implicit lambda parameter styles |
| Inferred compile-time type | Dynamic typing; it is not JavaScript-style var |
var a = new int[] {1, 2}; | var a = {1, 2}; |
var names = List.of("Ada", "Linus"); // List<String>
var count = 10; // int, not Integer
// Valid: all lambda parameters use var
BiFunction<String, String, Integer> len =
(var a, var b) -> a.length() + b.length();
Numeric, boolean, and text traps
| Topic | Rule |
|---|
| Binary numeric promotion | byte, short, and char promote to int in arithmetic |
| Promotion order | double > float > long > int |
| Compound assignment | Includes implicit cast: b += 1 can compile where b = b + 1 may not |
| Integer division | Truncates toward zero |
Floating NaN | Comparisons with NaN are false except != |
| Wrapper equality | Prefer equals; do not rely on == object identity |
String immutability | Concatenation creates new strings unless optimized by compiler/runtime |
StringBuilder.equals | Does not compare contents unless overridden by another class; use toString() or compare manually |
| Text blocks | Preserve newlines and use incidental indentation rules |
_ identifier | Reserved; do not use as a variable name in standard Java 21 code |
Control flow
| Feature | Key exam rule |
|---|
if | Condition must be boolean, not numeric |
switch statement | May fall through with colon labels unless break, return, throw, etc. |
switch expression | Must produce a value on every path; use yield in block arms |
| Arrow switch label | No fall-through |
for | Init/update sections can contain comma-separated expressions |
Enhanced for | Iterates arrays or Iterable; loop variable is a copy/reference, not the collection slot |
| Labels | Work with loops/blocks; break label exits labeled statement; continue label targets loop |
int result = switch (grade) {
case "A", "B" -> 1;
case "C" -> {
int adjusted = curve();
yield adjusted;
}
default -> 0;
};
OOP, interfaces, records, sealed classes, and patterns
Overloading vs overriding
| Feature | Overloading | Overriding |
|---|
| Resolved | Compile time | Runtime |
| Based on | Reference type and argument types | Actual object type |
| Return type only | Cannot overload by return type only | Covariant return allowed |
| Access | Any valid overload | Cannot reduce visibility |
| Exceptions | Independent | Checked exceptions must be same/narrower; unchecked flexible |
| Static methods | Can be overloaded | Hidden, not overridden |
| Private methods | Can be overloaded | Not inherited; not overridden |
final methods | Can be overloaded | Cannot be overridden |
class Parent {
Number value() throws IOException { return 1; }
static void label() {}
}
class Child extends Parent {
@Override
Integer value() throws FileNotFoundException { return 2; } // covariant + narrower
static void label() {} // hides, does not override
}
Interface rules
| Rule | Detail |
|---|
| Fields | Implicitly public static final |
| Abstract methods | Implicitly public abstract unless default, static, or private |
| Default methods | Inherited unless class/superclass method wins or conflict must be resolved |
| Static interface methods | Called with interface name, not inherited as instance methods |
| Private interface methods | Helper methods for default/static methods |
| Conflict rule | Class wins; otherwise most specific interface wins; otherwise implementing class must override |
Nested, local, and anonymous classes
| Type | Key points |
|---|
| Static nested class | No enclosing instance required |
| Inner member class | Requires enclosing instance; can access outer instance members |
| Local class | Declared inside block; can access effectively final local variables |
| Anonymous class | Extends one class or implements one interface; cannot declare constructor |
| Lambda vs anonymous class | In lambda, this refers to enclosing instance; in anonymous class, this is the anonymous object |
Enums
| Rule | Detail |
|---|
| Constants first | Enum constants must appear before fields/methods |
| Constructor | Implicitly private; never called with new |
| Methods/fields | Allowed after semicolon |
| Per-constant behavior | Constants can override abstract/regular methods |
| API | values(), valueOf(String), name(), ordinal() |
| Collections | Prefer EnumSet and EnumMap for enum keys/sets |
| Trap | Do not persist or compare business meaning with ordinal() |
Records
Records are transparent data carriers, but they are only shallowly immutable.
| Feature | Rule |
|---|
| Declaration | record Point(int x, int y) {} |
| Generated members | Private final fields, public accessors x(), y(), canonical constructor, equals, hashCode, toString |
| Inheritance | Records are final and extend java.lang.Record |
| Interfaces | Records can implement interfaces |
| Extra fields | Static fields allowed; additional instance fields are not |
| Compact constructor | Validate/normalize parameters; compiler assigns fields after body |
| Mutability trap | A record component can reference a mutable object |
record Money(BigDecimal amount, Currency currency) {
Money {
Objects.requireNonNull(amount);
Objects.requireNonNull(currency);
amount = amount.stripTrailingZeros(); // normalize parameter
}
}
Sealed classes and interfaces
| Modifier | Meaning |
|---|
sealed | Restricts which classes/interfaces may directly extend/implement |
permits | Lists direct permitted subclasses unless inferable in same source context |
final subclass | Stops the hierarchy |
sealed subclass | Continues restricted hierarchy |
non-sealed subclass | Reopens extension below that type |
sealed interface Shape permits Circle, Rectangle {}
record Circle(double radius) implements Shape {}
record Rectangle(double width, double height) implements Shape {}
Pattern matching and Java 21 switch
| Feature | Exam rule |
|---|
instanceof pattern | Pattern variable is in scope only where definitely matched |
| Record pattern | Deconstructs records, including nested record patterns |
Pattern switch | Supports type patterns and guarded patterns |
| Guard | Use when, not a separate if label |
| Dominance | Broader pattern before narrower pattern can make latter unreachable |
| Exhaustiveness | Switch expressions and pattern switches must cover all possibilities |
null | Without case null, a null selector throws NullPointerException |
static String describe(Object obj) {
return switch (obj) {
case null -> "null";
case String s when s.isBlank() -> "blank string";
case String s -> "string: " + s;
case Integer i -> "integer: " + i;
case Point(int x, int y) -> "point " + x + "," + y;
default -> "other";
};
}
Generics, arrays, and collections
Generics essentials
| Concept | Rule |
|---|
| Type erasure | Generic type info mostly removed at runtime |
| Invariance | List<Integer> is not a subtype of List<Number> |
? extends T | Producer: read as T; cannot add non-null values |
? super T | Consumer: can add T; read as Object |
List<?> | Read as Object; add only null |
| Generic arrays | new T[] and new List<String>[] are invalid |
| Reifiable types | Runtime-known types, such as raw types and unbounded wildcards |
| Raw types | Compile with warnings; can cause heap pollution |
| Erasure collision | Cannot overload methods whose erased signatures conflict |
PECS: producer extends, consumer super.
static double total(List<? extends Number> nums) {
return nums.stream().mapToDouble(Number::doubleValue).sum();
}
static void addDefaults(List<? super Integer> nums) {
nums.add(1);
nums.add(2);
}
Arrays vs collections
| Feature | Arrays | Generics/collections |
|---|
| Variance | Covariant: String[] is an Object[] | Invariant: List<String> is not List<Object> |
| Runtime type | Reified | Erased |
| Bad store | Can throw ArrayStoreException | Usually compile-time error |
| Size | Fixed | Usually dynamic |
| Primitive support | Direct: int[] | Use wrappers or primitive streams |
Collection selection matrix
| Need | Choose | Notes |
|---|
| Ordered, index-based, duplicates | ArrayList | Fast random access; middle insert/remove can be costly |
| Frequent add/remove at ends | ArrayDeque | Preferred stack/queue implementation; no null elements |
| Unique elements, no order guarantee | HashSet | Requires consistent equals/hashCode |
| Unique elements, insertion order | LinkedHashSet | Java 21 sequenced behavior is useful |
| Unique sorted elements | TreeSet | Uses natural order or Comparator; compare consistency matters |
| Key-value lookup | HashMap | Allows one null key and null values |
| Key-value insertion order | LinkedHashMap | Useful for predictable iteration/LRU-style patterns |
| Sorted keys | TreeMap | Keys must be comparable or comparator supplied |
| Enum keys/sets | EnumMap, EnumSet | Compact and efficient |
| Concurrent key-value access | ConcurrentHashMap | Does not allow null keys/values |
| Read-heavy concurrent list | CopyOnWriteArrayList | Writes copy the array; expensive for frequent mutation |
| Producer/consumer handoff | BlockingQueue | Coordinates threads |
Mutability and factory traps
| API | Behavior |
|---|
List.of, Set.of, Map.of | Unmodifiable; reject nulls; duplicate set elements/map keys fail |
List.copyOf | Unmodifiable copy; rejects nulls |
Arrays.asList(array) | Fixed-size list backed by array; set writes through; add/remove fail |
Collections.unmodifiableList(list) | Unmodifiable view backed by original list |
Stream.toList() | Unmodifiable result |
Collectors.toList() | No guaranteed implementation or mutability contract |
Set duplicate logic | Based on equals/hashCode for hash sets; comparator/compareTo for sorted sets |
Sequenced collections in Java 21
| Interface | Adds/standardizes | Typical implementations |
|---|
SequencedCollection<E> | getFirst, getLast, addFirst, addLast, removeFirst, removeLast, reversed | List, Deque, linked collections |
SequencedSet<E> | Sequenced collection with uniqueness | LinkedHashSet, sorted/navigable sets |
SequencedMap<K,V> | First/last entries and reversed view | LinkedHashMap, sorted/navigable maps |
Lambdas, method references, streams, and Optional
Functional interfaces
| Interface | Method | Use |
|---|
Predicate<T> | boolean test(T) | Filtering, validation |
Function<T,R> | R apply(T) | Mapping |
Consumer<T> | void accept(T) | Side-effect operation |
Supplier<T> | T get() | Lazy value creation |
UnaryOperator<T> | T apply(T) | Same input/output type |
BinaryOperator<T> | T apply(T,T) | Combine same-type values |
Comparator<T> | int compare(T,T) | Sorting |
Callable<V> | V call() throws Exception | Task with result/checked exception |
Runnable | void run() | Task without result |
Primitive specializations avoid boxing: IntPredicate, IntFunction<R>, ToIntFunction<T>, IntSupplier, IntConsumer, IntUnaryOperator, ObjIntConsumer<T>.
| Form | Example | Equivalent idea |
|---|
| Static | Integer::parseInt | s -> Integer.parseInt(s) |
| Bound instance | name::toUpperCase | () -> name.toUpperCase() |
| Unbound instance | String::length | s -> s.length() |
| Constructor | ArrayList::new | () -> new ArrayList<>() |
| Array constructor | String[]::new | n -> new String[n] |
Stream pipeline rules
| Rule | Detail |
|---|
| Source | Collection, array, generator, file lines, etc. |
| Intermediate ops | Lazy; return another stream |
| Terminal ops | Trigger processing and close the pipeline for reuse |
| Stateless ops | map, filter, peek |
| Stateful ops | sorted, distinct, limit, skip |
| Short-circuiting | findFirst, findAny, anyMatch, limit |
| Parallel streams | Avoid shared mutable state; ordering can reduce performance |
| Side effects | Dangerous in map, filter, peek, especially parallel |
| Single use | Reusing a consumed stream throws IllegalStateException |
Common stream operations
| Need | Operation |
|---|
| Transform one-to-one | map |
| Transform one-to-many | flatMap |
| Primitive numeric stream | mapToInt, mapToLong, mapToDouble |
| Remove duplicates | distinct |
| Sort | sorted() or sorted(comparator) |
| Aggregate with identity | reduce(identity, accumulator) |
| Mutable reduction | collect(...) |
| Group | Collectors.groupingBy |
| Partition by boolean | Collectors.partitioningBy |
| Duplicate map keys | Use Collectors.toMap(key, value, merge) |
Map<Department, Long> counts =
employees.stream()
.filter(Employee::active)
.collect(Collectors.groupingBy(
Employee::department,
Collectors.counting()
));
Map<String, Integer> salaryByName =
employees.stream()
.collect(Collectors.toMap(
Employee::name,
Employee::salary,
Integer::max
));
Optional traps
| API | Rule |
|---|
get() | Throws if empty; prefer safer methods |
orElse(value) | Eagerly evaluates value |
orElseGet(supplier) | Lazily calls supplier only if empty |
orElseThrow() | Throws NoSuchElementException if empty |
map | Wraps mapped result, empty if mapper returns null |
flatMap | Mapper returns Optional directly |
ifPresentOrElse | Handles present and empty branches |
| Field/parameter use | Usually avoid Optional as fields or parameters; best as return type |
Exceptions and resource management
Exception hierarchy
| Type | Checked? | Must catch/declare? |
|---|
Throwable | Usually yes, except Error/RuntimeException branches | Usually |
Exception | Yes, except RuntimeException branch | Yes |
RuntimeException | No | No |
Error | No | No; generally do not catch |
| Custom checked exception | Extend Exception | Yes |
| Custom unchecked exception | Extend RuntimeException | No |
Catching and throwing rules
| Rule | Example/trap |
|---|
| Catch specific before general | catch (IOException) before catch (Exception) |
| Multi-catch alternatives | Cannot be related by subclassing |
| Multi-catch variable | Effectively final |
| Overriding checked exceptions | Same or narrower checked exceptions only |
finally | Runs after try/catch unless VM exits or fatal termination |
Return in finally | Can suppress/override earlier return or exception; avoid |
| Precise rethrow | Compiler can infer narrower thrown types for effectively final catch variable |
Try-with-resources
Resources must implement AutoCloseable or Closeable.
try (BufferedReader reader = Files.newBufferedReader(path);
BufferedWriter writer = Files.newBufferedWriter(out)) {
writer.write(reader.readLine());
}
| Rule | Detail |
|---|
| Close order | Reverse declaration order |
| Resource variable | Effectively final variables can be used as resources |
| Primary exception | Exception from try body wins |
| Suppressed exceptions | Exceptions from close() are attached to primary exception |
AutoCloseable.close | Can throw Exception |
Closeable.close | Throws IOException; close should be idempotent |
Date and time API
| Type | Represents | Zone? |
|---|
LocalDate | Date only | No |
LocalTime | Time only | No |
LocalDateTime | Date and time | No |
ZonedDateTime | Date/time with time zone rules | Yes |
OffsetDateTime | Date/time with fixed offset | Offset only |
Instant | Machine timestamp | UTC instant |
Period | Date-based amount | Years/months/days |
Duration | Time-based amount | Seconds/nanos |
ZoneId | Region rules, such as Europe/Paris | Yes |
ZoneOffset | Fixed offset, such as +02:00 | Offset only |
| Trap | Correct reasoning |
|---|
LocalDateTime is a moment | It is not a global instant until combined with a zone/offset |
Period.ofDays(1) equals Duration.ofDays(1) | Around DST, calendar day and 24 hours can differ |
| Date/time types mutate | Java time types are immutable |
yyyy and YYYY are interchangeable | YYYY is week-based year; use yyyy for calendar year |
MM and mm are interchangeable | MM month; mm minute |
DateTimeFormatter fmt =
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")
.withLocale(Locale.US);
LocalDate date = LocalDate.parse("2026-06-18");
String text = LocalDateTime.now().format(fmt);
BigDecimal and numeric precision
| Need | Use / avoid |
|---|
| Exact decimal money-like values | BigDecimal |
| Construct exact decimal | new BigDecimal("0.10") or BigDecimal.valueOf(...) |
| Avoid | new BigDecimal(0.10) due binary floating approximation |
| Compare numeric value | compareTo |
| Compare value and scale | equals |
| Division with non-terminating result | Provide scale/rounding mode |
BigDecimal a = new BigDecimal("1.0");
BigDecimal b = new BigDecimal("1.00");
boolean sameNumber = a.compareTo(b) == 0; // true
boolean sameObjectValue = a.equals(b); // false: scale differs
Localization
| API | Use |
|---|
Locale | Language, region, variant preferences |
ResourceBundle | Locale-specific messages/resources |
NumberFormat | Number, percent, currency formatting |
DateTimeFormatter | Locale-aware date/time formatting |
MessageFormat | Parameterized localized messages |
Collator | Locale-sensitive string comparison |
| Trap | Rule |
|---|
| Hard-coded strings | Use resource bundles for localizable text |
| Missing bundle key | MissingResourceException |
| Default locale | Can affect formatting/tests unexpectedly |
MessageFormat quotes | Single quotes escape text; doubled single quote gives literal quote |
| Currency formatting | Locale affects display format; currency itself may need explicit control |
I/O, NIO.2, and serialization awareness
Byte vs character APIs
| Need | API family |
|---|
| Binary bytes | InputStream, OutputStream |
| Text characters | Reader, Writer |
| Buffered byte I/O | BufferedInputStream, BufferedOutputStream |
| Buffered text I/O | BufferedReader, BufferedWriter |
| Formatted text output | PrintWriter, PrintStream |
| Object serialization | ObjectInputStream, ObjectOutputStream |
| Trap | Correct rule |
|---|
| Reader/writer are for bytes | They are for characters |
| Platform default charset is always safe | Prefer explicit Charset, such as StandardCharsets.UTF_8 |
PrintWriter throws normal checked exceptions on write | It often records errors; check checkError() |
| Serialization is safe for untrusted data | Treat deserialization of untrusted data as dangerous |
NIO.2 Path and Files
| API | Use |
|---|
Path.of(...) | Create a path object |
resolve | Append/resolve child path |
relativize | Path from one path to another |
normalize | Remove redundant . and .. syntactically |
toAbsolutePath | Convert to absolute path syntactically |
toRealPath | Resolve real existing path, symlinks, file system checks |
Files.exists | Existence check; race-prone if followed by action |
Files.copy | Copy file/stream |
Files.move | Move/rename |
Files.delete | Delete or throw |
Files.deleteIfExists | Delete if present |
Files.walk | Recursive lazy stream; close it |
Files.list | Lazy directory stream; close it |
Files.find | Recursive search with predicate |
try (Stream<Path> paths = Files.walk(root)) {
paths.filter(Files::isRegularFile)
.forEach(System.out::println);
}
Path traversal guard pattern
Path base = Path.of("/app/uploads").toRealPath();
Path candidate = base.resolve(userInput).normalize();
if (!candidate.startsWith(base)) {
throw new SecurityException("Invalid path");
}
For existing files, use toRealPath() where appropriate to account for symbolic links and actual file-system resolution.
Concurrency and virtual threads
Threading building blocks
| Need | API |
|---|
| Define no-result task | Runnable |
| Define result task | Callable<V> |
| Run task directly | Thread |
| Manage task execution | ExecutorService |
| Delayed/periodic tasks | ScheduledExecutorService |
| Result handle | Future<V> |
| Completion pipelines | CompletableFuture |
| CPU work splitting | Fork/join, parallel streams |
| High-throughput blocking I/O | Virtual threads |
| Shared-state protection | synchronized, locks, atomics, concurrent collections |
Executors and futures
| Operation | Meaning |
|---|
execute(Runnable) | Fire-and-forget; no result |
submit(Callable) | Returns Future<V> |
submit(Runnable) | Returns Future<?> |
Future.get() | Blocks; wraps task exception in ExecutionException |
cancel(true) | Requests cancellation and may interrupt |
shutdown() | Stop accepting new tasks; existing tasks continue |
shutdownNow() | Attempts to interrupt/cancel queued/running tasks |
awaitTermination | Waits after shutdown request |
Virtual threads in Java 21
Virtual threads are standard in Java 21 and are useful for large numbers of blocking tasks.
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
Future<String> result = executor.submit(() -> fetchRemoteValue());
System.out.println(result.get());
}
| Choose virtual threads when | Avoid assuming |
|---|
| Many blocking I/O tasks | They make CPU-bound work faster automatically |
| Simple thread-per-request style | You need large fixed thread pools |
| Code is mostly blocking APIs | Shared mutable state becomes safe |
| You want simpler concurrency code | Synchronization/pinning concerns disappear |
Synchronization and memory visibility
| Tool | Use | Trap |
|---|
synchronized | Mutual exclusion and visibility | Lock is per object/class monitor |
volatile | Visibility for reads/writes | Not atomic for count++ |
AtomicInteger | Atomic CAS-style updates | Compound invariants may still need locks |
LongAdder | High-contention counters | Not for exact instantaneous value under concurrent updates |
ReentrantLock | Explicit lock/unlock, try-lock | Always unlock in finally |
wait/notify | Low-level coordination | Must hold monitor; test condition in loop |
sleep | Pause current thread | Does not release lock |
join | Wait for thread completion | Can be interrupted |
class Counter {
private final AtomicInteger value = new AtomicInteger();
int increment() {
return value.incrementAndGet();
}
}
Concurrent collections
| Collection | Use |
|---|
ConcurrentHashMap | Concurrent key-value access; no null keys/values |
CopyOnWriteArrayList | Many reads, few writes |
BlockingQueue | Producer/consumer coordination |
ConcurrentLinkedQueue | Non-blocking queue |
ConcurrentSkipListMap | Concurrent sorted map |
JDBC quick reference
Core interfaces
| Interface | Role |
|---|
DriverManager | Obtain connections using JDBC URL |
DataSource | Preferred managed connection factory in many applications |
Connection | Database session and transaction boundary |
Statement | Static SQL; avoid for user input |
PreparedStatement | Parameterized SQL; helps prevent SQL injection |
CallableStatement | Stored procedures |
ResultSet | Cursor over query results |
SQLException | Database access error with SQL state/vendor code |
JDBC operation rules
| Rule | Detail |
|---|
| Indexing | Parameters and result-set column indexes are 1-based |
| Cursor | ResultSet starts before first row; call next() |
executeQuery | For SQL returning a ResultSet |
executeUpdate | For DML/DDL returning update count |
execute | For unknown/multiple result types |
| Auto-commit | Common default is auto-commit enabled on new connections |
| Transaction | Disable auto-commit, then commit or rollback |
| Resources | Close ResultSet, Statement, and Connection; use try-with-resources |
| Batch | addBatch, executeBatch |
| SQL injection | Use bind parameters, not string concatenation |
String sql = "select name from employee where id = ?";
try (Connection con = dataSource.getConnection();
PreparedStatement ps = con.prepareStatement(sql)) {
ps.setLong(1, employeeId);
try (ResultSet rs = ps.executeQuery()) {
if (rs.next()) {
return rs.getString("name");
}
}
}
Transaction pattern
try (Connection con = dataSource.getConnection()) {
con.setAutoCommit(false);
try {
updateAccount(con, from);
updateAccount(con, to);
con.commit();
} catch (SQLException e) {
con.rollback();
throw e;
}
}
Annotations and secure coding
Annotation rules
| Feature | Rule |
|---|
| Retention | SOURCE, CLASS, RUNTIME |
| Target | Restricts where annotation may appear |
| Element types | Primitive, String, Class, enum, annotation, arrays of these |
| Defaults | Annotation elements can declare default values |
| Null | Annotation element values cannot be null |
| Marker annotation | No elements |
| Single-value convention | Element named value may omit name |
| Repeatable annotation | Uses @Repeatable(container) |
@Inherited | Applies only to class inheritance, not methods/interfaces generally |
| Type-use annotations | Can target uses of types, not just declarations |
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@interface Audited {
String value() default "standard";
}
Secure coding checklist
| Risk | Safer approach |
|---|
| SQL injection | PreparedStatement bind parameters |
| Path traversal | Resolve against trusted base, normalize, validate prefix, handle symlinks |
| Mutable internals | Defensive copies or unmodifiable views |
| Mutable record components | Copy mutable inputs/accessors if invariants matter |
| Deserialization attacks | Avoid untrusted deserialization; validate/filter when used |
| Sensitive data in strings | Prefer limited-lifetime structures where practical |
| Broad reflection | Use narrow opens ... to rather than open modules/packages |
| Overbroad exceptions | Catch what you can handle; preserve cause |
| Resource leaks | Try-with-resources |
| Time zone bugs | Store instants/offsets deliberately; format at boundaries |
Common 1Z0-830-style traps checklist
| Question pattern | Fast check |
|---|
| “Which overload runs?” | Use declared reference type and compile-time argument types |
| “Which override runs?” | Use actual object type, unless method is static/private/final |
| Generic wildcard confusion | extends read, super write |
equals/hashCode with hash collections | Equal objects must have equal hash codes |
TreeSet removes “duplicates” unexpectedly | Comparator/compareTo defines uniqueness |
| Stream result missing side effects | Intermediate operations are lazy until terminal op |
Optional.orElse(expensive()) | Argument evaluated even when value present |
switch with patterns | Check dominance, exhaustiveness, and null |
| Record immutability | Record is shallowly immutable only |
List.of mutation | Throws UnsupportedOperationException |
Arrays.asList resize | add/remove fail; set works |
| Date pattern typo | MM month, mm minute; yyyy calendar year |
| JDBC parameters | Start at 1, not 0 |
| Try-with-resources exception | Close exceptions may be suppressed |
volatile count++ | Still not atomic |
| Module access | public is not enough without exported package |
normalize() security | It does not verify existence or symlinks |
| Preview syntax | Not exam-safe unless explicitly enabled |
Practical next step
Use this Quick Reference as an error-log checklist: after each Oracle Java SE 21 Developer Professional (1Z0-830) practice set, mark every missed question by rule category, then write and run a minimal Java 21 snippet that proves the correct behavior.