Home / software-development / Java SE 21 Developer Professional (1Z0-830) / Cheat Sheet
Java SE 21 Developer Professional (1Z0-830)

1Z0-830 Cheat Sheet

1Z0-830 Tests What the Compiler Rejects and Prints — Not Java You Write Daily

This professional exam targets developers fluent in modern Java. Expect dense snippets on records, sealed types, pattern matching and virtual threads, where the right answer is often does not compile.

Check Your Readiness →
Among the harder certs
Avg: Not published by Oracle
Pass: 750 / 1000
Most candidates understand Java SE 21 Developer Professional (1Z0-830) concepts — and still fail. This exam tests how you apply knowledge under pressure.

1Z0-830 Topic Map (ten Oracle sections grouped into nine)

Oracle lists ten sections without weights; I/O and Localization are combined here to fit. Fifty items in 120 minutes leaves over two minutes each, which you need: most present code and ask for output or the failing line, and several are multiple-select.

  1. 01
    Date, Time, Text, Numeric and Boolean Values (weight not published) — promotion, Integer cache, text blocks, Period vs. Duration, DST
  2. 02
    Program Flow (weight not published) — switch expressions, yield, exhaustiveness, labeled break and continue
  3. 03
    Object-Oriented Concepts (weight not published) — records, sealed hierarchies, pattern dominance, overload resolution, init order
  4. 04
    Exceptions (weight not published) — catch ordering, multi-catch rules, try-with-resources close order, suppressed exceptions
  5. 05
    Arrays and Collections (weight not published) — List.of vs. Arrays.asList, remove(int), sequenced collections, TreeSet duplicates
  6. 06
    Streams and Lambdas (weight not published) — laziness, single use, collectors, Optional, effectively final capture
  7. 07
    Packaging and Deploying (weight not published) — module-info directives, services, automatic and unnamed modules, jlink
  8. 08
    Concurrency (weight not published) — platform vs. virtual threads, executors, locks, atomics, parallel streams
  9. 09
    I/O and Localization (weight not published) — NIO.2 Path methods, serialization, bundle lookup, number formatting

Wrong instinct vs correct approach

Two closeable records are declared in one try header; the body prints t and throws
✕ Wrong instinct

Output is t, then the catch, then both close calls

✓ Correct approach

Resources close in reverse declaration order immediately after the body, before catch and finally. With R("1") and R("2") the output is tc2c1xf. A close() exception thrown after a body exception is attached as suppressed.

Class B extends A; both declare field n and method get(); code uses A a = new B()
✕ Wrong instinct

Both a.n and a.get() return the subclass value B

✓ Correct approach

Fields and static methods are hidden and resolve by reference type; only instance methods are polymorphic. a.n reads A's field and a.get() runs B's override, so a.n + a.get() prints AB.

A Collectors.partitioningBy call with counting() runs where every element matches the predicate
✕ Wrong instinct

The map holds only the true key

✓ Correct approach

partitioningBy always creates both Boolean keys, so the empty side maps to 0 or an empty list. counting() yields Long values, so declaring Map<Boolean, Integer> fails to compile. toMap throws on duplicate keys without a merge function.

A shared int counter is incremented by several platform threads; the field is marked volatile
✕ Wrong instinct

volatile makes the final total exact

✓ Correct approach

volatile guarantees visibility only; count++ is a read-modify-write that still interleaves. Use AtomicInteger.incrementAndGet, synchronized or a ReentrantLock released in finally. Where nothing enforces order, choose the answer saying output cannot be determined.

Know these cold

  • ▸ Integer == is true for 127 but false for 128; compare boxed values with equals
  • ▸ byte + byte is int and needs a cast; short s += 5 compiles via implicit cast
  • ▸ Overload phases — xact or widening, then boxing, then varargs; m(5) picks m(long) over m(Integer)
  • ▸ Arrow cases never fall through; a switch expression over int needs default
  • ▸ Inside a switch expression block, return a value with yield, never return
  • ▸ List.of rejects nulls and every change; Arrays.asList allows set, writes through, but not add
  • ▸ list.remove(1) on List<Integer> removes index 1; remove(Integer.valueOf(1)) removes the value
  • ▸ Multi-catch types cannot be related by subclassing; catching an unthrowable checked exception fails to compile
  • ▸ Lambdas capture only effectively final locals; a later i++ anywhere breaks compilation
  • ▸ Future.get wraps task failures in ExecutionException; plusMonths on 31 January clamps to month end

Can you answer these without checking your notes?

In this scenario: "Two closeable records are declared in one try header; the body prints t and throws" — what should you do first?
Resources close in reverse declaration order immediately after the body, before catch and finally. With R("1") and R("2") the output is tc2c1xf. A close() exception thrown after a body exception is attached as suppressed.
In this scenario: "Class B extends A; both declare field n and method get(); code uses A a = new B()" — what should you do first?
Fields and static methods are hidden and resolve by reference type; only instance methods are polymorphic. a.n reads A's field and a.get() runs B's override, so a.n + a.get() prints AB.
In this scenario: "A Collectors.partitioningBy call with counting() runs where every element matches the predicate" — what should you do first?
partitioningBy always creates both Boolean keys, so the empty side maps to 0 or an empty list. counting() yields Long values, so declaring Map<Boolean, Integer> fails to compile. toMap throws on duplicate keys without a merge function.

Common Exam Mistakes — What candidates get wrong

Calling getR() on a record or assigning fields in a compact constructor

Record accessors use the component name, so Circle(double r) exposes r(). A compact constructor may validate or reassign the parameter, but this.r = r fails because fields are assigned automatically afterwards. Records cannot declare extra instance fields; static ones are allowed.

Ordering type patterns from general to specific in a switch

case CharSequence c before case String s is a compile error: the String label is dominated. Put narrower patterns and guarded ones (case Circle c when c.r() == 0) first. Without case null, a null selector throws NullPointerException.

Leaving a permitted subclass of a sealed type without a modifier

Every direct subtype named in permits must be final, sealed or non-sealed, or compilation fails. Records are implicitly final, so they qualify. A switch covering every permitted subtype is exhaustive and needs no default branch.

Expecting an unjoined virtual thread to keep the JVM running

Virtual threads are always daemon threads, so main can exit before they print. Use join, or Executors.newVirtualThreadPerTaskExecutor() in try-with-resources, since ExecutorService.close waits for submitted tasks. Never pool virtual threads in a fixed-size executor.

Expecting peek output from a stream with no terminal operation

Intermediate operations are lazy, so Stream.of(1, 2, 3).peek(System.out::print).map(n -> n * 2) prints nothing. A stream is single-use: a second terminal call throws IllegalStateException. IntStream.average() returns OptionalDouble, not double.

Resources to help you pass Java SE 21 Developer Professional on your first attempt

1Z0-830 punishes one missed modifier. See whether you spot what the compiler would reject.