Browse Exams — Mock Exams & Practice Tests

1Z0-829 Cheatsheet — Java SE 17 (Language, Generics, Streams, Concurrency)

High-yield 1Z0-829 cheat sheet for Java SE 17: rules, APIs, patterns, and pitfalls across language features, generics, streams, exceptions, and concurrency.

On this page

Use this for last‑mile review and for building your personal “mistake log”.

This cheatsheet is intentionally detailed; skim headings first, then deep-read the sections that match your weak objectives.

How to use this cheatsheet

  • Read the Syllabus first so you know what you’re accountable for.
  • Use this cheatsheet to close gaps after you miss a question: find the rule, write a 5–10 line snippet that demonstrates it, and re-test yourself.
  • Focus on correctness details: most 1Z0‑829 questions are “which compiles / what prints / what throws”.

High-yield traps (read first)

  • Numeric promotion: byte + byte becomes int; char participates in numeric promotion; compound assignment can hide casts.
  • Overload resolution: exact match > primitive widening > boxing > varargs (but “most specific” still matters).
  • String pooling: == compares references; equals compares content; compile-time constants can be interned.
  • Immutable factories: List.of(...), Set.of(...), Map.of(...) are unmodifiable and reject null.
  • Stream single-use: a stream is consumed after a terminal op; reuse throws IllegalStateException.
  • Optional: orElse(...) evaluates eagerly; orElseGet(...) is lazy.
  • try-with-resources: close order is reverse declaration; suppressed exceptions can appear.
  • Concurrency: volatile gives visibility, not atomicity; synchronized gives mutual exclusion + visibility.
  • Comparator vs equals: inconsistent ordering can break sorted sets/maps.

Language and types

Primitive widening and narrowing

Widening conversions (no cast needed):

FromCan widen to
byteshort, int, long, float, double
shortint, long, float, double
charint, long, float, double
intlong, float, double
longfloat, double
floatdouble

Narrowing conversions (cast required, potential truncation/overflow):

1int i = 130;
2byte b = (byte) i; // -126 (overflow)

Numeric promotion rules you must memorize

  • Binary numeric promotion promotes smaller-than-int types to int first.
  • If either operand is double, result is double; else if float, result is float; else if long, result is long; else int.
1byte a = 1, b = 2;
2// byte c = a + b; // does not compile: result is int
3int c = a + b;

Compound assignment hides casts

1byte x = 1;
2x += 200;        // compiles (implicit cast), overflow at runtime -> -55
3// x = x + 200;  // does not compile (x + 200 is int)

Autoboxing / unboxing pitfalls

1Integer n = null;
2// int x = n; // NullPointerException (unboxing null)
3
4Integer a = 127, b = 127;
5System.out.println(a == b);      // true (cached)
6Integer c = 128, d = 128;
7System.out.println(c == d);      // false (not necessarily cached)
8System.out.println(c.equals(d)); // true

var rules (local inference)

  • var requires an initializer; it cannot be null alone.
  • var is local (and for loop index); it’s not for fields or method parameters (unless a lambda parameter uses var).
1var list = java.util.List.of(1, 2, 3); // inferred List<Integer>
2// var x; // does not compile (no initializer)

String immutability and concatenation

  • String is immutable.
  • + creates new Strings (compiler may optimize compile-time constants).
  • Use StringBuilder when you’re building in loops.
1String s = "a";
2s.concat("b");
3System.out.println(s); // "a" (concat returns new String)

Text blocks (Java 15+) basics

1String json = """
2  {
3    "ok": true
4  }
5  """;
  • Text blocks include a newline at the end unless you suppress it with \ at line end.
  • Escapes still work, but you often need fewer of them.

Control flow essentials

switch statement rules

  • Supported selector types include byte, short, char, int, their wrappers, enum, and String.
  • case labels must be compile-time constants.
  • Without break, you fall through (switch statement).

switch expressions (Java 14+) basics

  • Arrow labels (case X ->) do not fall through.
  • For multi-statement cases, use a block and yield.
1int size = switch (s) {
2  case "S" -> 1;
3  case "M" -> 2;
4  default -> {
5    int n = s.length();
6    yield n;
7  }
8};

Loops and labels

1outer:
2for (int i = 0; i < 3; i++) {
3  for (int j = 0; j < 3; j++) {
4    if (i == 1) continue outer;
5  }
6}
  • Labels apply to statements; break label; exits that labeled statement, continue label; continues the labeled loop.

Methods and encapsulation

Overload resolution mental model

When multiple overloads could match, Java prefers (roughly):

  • exact match
  • primitive widening
  • boxing
  • varargs

And then picks the most specific among applicable candidates.

1static void f(long x) {}
2static void f(Integer x) {}
3static void f(int... x) {}
4
5f(1); // picks f(long) (widening beats boxing/varargs)

Varargs caveats

1static void g(int... x) {}
2g();          // ok: empty array
3g((int[])null); // ok: x is null (be careful)

Pass-by-value (including references)

1static void rebind(StringBuilder sb) { sb = new StringBuilder("x"); }
2static void mutate(StringBuilder sb) { sb.append("!"); }
3
4var sb = new StringBuilder("a");
5rebind(sb);
6System.out.println(sb); // "a"
7mutate(sb);
8System.out.println(sb); // "a!"

Access modifiers cheat table

ModifierSame classSame packageSubclass (other package)Anywhere
private
package-private
protected
public

Initialization order (common exam question)

For a new instance:

  • Static fields/blocks (once per class load, superclass first)
  • Instance fields/blocks (superclass first)
  • Constructor body (superclass constructor runs before subclass constructor body)
1class A { A(){ System.out.print("A"); } }
2class B extends A { B(){ System.out.print("B"); } }
3System.out.print(new B()); // prints "AB..."

Arrays (correctness basics)

  • Arrays are covariant: String[] is an Object[] (compile-time), but assignments can fail at runtime.
1Object[] arr = new String[1];
2arr[0] = 42; // ArrayStoreException at runtime

Inheritance and polymorphism

Overriding rules

  • Same signature (name + parameters), compatible return type (covariant allowed)
  • Cannot reduce visibility
  • For checked exceptions: cannot throw broader/new checked exceptions
  • @Override helps catch mistakes

Hiding vs overriding

  • Static methods are hidden, not overridden.
  • Fields are hidden, not overridden.
1class P { static void s(){ System.out.print("P"); } }
2class C extends P { static void s(){ System.out.print("C"); } }
3P p = new C();
4p.s(); // "P"

Interfaces and functional interfaces

  • Interface fields are implicitly public static final.
  • Interface methods can be abstract, default, static, and private (Java 9+).
  • Static interface methods are not inherited by implementing classes.

Default method conflicts (concept-level)

If two interfaces provide the same default method signature, the implementing class must override (or pick one via InterfaceName.super.method()).

Enums (high-yield)

  • Enum constructors are implicitly private.
  • Enum instances are singletons per constant.
  • switch works well with enums; prefer enums for closed sets.

Records (Java 16+) essentials

1record Point(int x, int y) {}
  • Records are final, immutable by design (components are final).
  • You can add methods, static fields, and implement interfaces.
  • Use compact constructors for validation:
1record User(String name) {
2  User {
3    if (name == null || name.isBlank()) throw new IllegalArgumentException();
4  }
5}

Sealed types (Java 17) essentials (concept-level)

1sealed interface Shape permits Circle, Rect {}
2final class Circle implements Shape {}
3non-sealed class Rect implements Shape {}
  • Sealed restricts who may extend/implement.
  • Permitted subtypes must be in the same module (or, in the unnamed module case, the same package).
  • Permitted types must declare final, sealed, or non-sealed.

Pattern matching for instanceof (Java 16+)

1if (obj instanceof String s) {
2  System.out.println(s.length());
3}
  • s is in scope only where the compiler can prove the pattern matched (flow scoping).
  • Pattern variables are effectively final.

Generics (the exam’s favorite pain point)

Invariance and why it matters

List<Integer> is not a subtype of List<Number>.

Wildcards and PECS

TypeReadWrite
List<? extends T>T (or subtype)❌ (except null)
List<? super T>Object✅ (T)
1static void addOnes(java.util.List<? super Integer> dst) {
2  dst.add(1);
3  dst.add(2);
4}

Type erasure (concept-level)

  • Generic type parameters are erased at runtime.
  • You generally can’t do new T() or if (x instanceof T).

Raw types and heap pollution

1java.util.List raw = new java.util.ArrayList<String>();
2raw.add(42);                 // compiles (warning)
3String s = (String) raw.get(0); // ClassCastException

Collections (what to know quickly)

Common implementations cheat table

StructureTypical useOrderingAllows nullNotes
ArrayListfast random accessinsertion orderresizing array
LinkedListdeque/queueinsertion orderslow random access
HashSetmembership testsnoneuses hashCode/equals
TreeSetsorted setsortedusually ❌comparator/Comparable
HashMapkey/value lookupnone✅ (1 null key)hashCode/equals
LinkedHashMappredictable iterationinsertion/access orderLRU caches
TreeMapsorted mapsorted by keyusually ❌comparator/Comparable

Immutable vs unmodifiable vs mutable

  • List.of(...) and List.copyOf(...) produce unmodifiable collections (no structural modification).
  • Collections.unmodifiableList(x) returns a view; if x changes, the view reflects it.
1var a = new java.util.ArrayList<>(java.util.List.of(1, 2));
2var v = java.util.Collections.unmodifiableList(a);
3a.add(3);
4System.out.println(v); // [1, 2, 3]

subList is a view

1var list = new java.util.ArrayList<>(java.util.List.of(1, 2, 3, 4));
2var sub = list.subList(1, 3); // [2, 3]
3sub.set(0, 99);
4System.out.println(list); // [1, 99, 3, 4]

Lambdas and functional interfaces

Capture rules

  • You can capture local variables only if they’re effectively final.
1int x = 1;
2java.util.function.IntSupplier s = () -> x;
3// x++; // does not compile (x no longer effectively final)

Checked exceptions and lambdas

Functional interface method signatures define what checked exceptions you may throw. If it doesn’t declare checked exceptions, you can’t throw them directly in the lambda.

Streams (what compiles, what runs, what returns)

Pipeline structure

  • Source → zero or more intermediate ops → terminal op
  • Intermediate ops are lazy; terminal triggers execution.
1var out = java.util.stream.Stream.of("a", "bb", "ccc")
2  .filter(s -> s.length() > 1)
3  .map(String::toUpperCase)
4  .toList();

Single-use rule

1var s = java.util.stream.Stream.of(1, 2, 3);
2s.count();
3// s.count(); // IllegalStateException

Common terminal return types

OperationReturns
count()long
findFirst()Optional<T>
min/max(comparator)Optional<T>
allMatch/anyMatch/noneMatchboolean
reduce(...)depends (Optional<T> or T)
collect(...)depends (often List, Map, etc.)

reduce gotchas (concept-level)

  • Identity must be neutral.
  • Accumulator/combiner must be associative for parallel correctness.

Collectors you should recognize

1var byLen = java.util.stream.Stream.of("a","bb","ccc")
2  .collect(java.util.stream.Collectors.groupingBy(String::length));
3// Map<Integer, List<String>>
1var joined = java.util.stream.Stream.of("a","b","c")
2  .collect(java.util.stream.Collectors.joining(","));
3// "a,b,c"

Optional rules

1Optional<String> o = Optional.of("x");
2o.map(String::length); // Optional<Integer>
3
4o.orElse(expensive());     // expensive() runs even if o is present
5o.orElseGet(() -> expensive()); // lazy

Exceptions and try-with-resources

Checked vs unchecked

  • Checked: must be caught or declared (e.g., IOException)
  • Unchecked: RuntimeException subclasses (e.g., NullPointerException)

Catch ordering

Catch more specific exceptions before broader ones.

1try { /* ... */ }
2catch (java.io.FileNotFoundException e) {}
3catch (java.io.IOException e) {}

try-with-resources close order and suppression

1try (var in = new java.io.ByteArrayInputStream(new byte[0]);
2     var out = new java.io.ByteArrayOutputStream()) {
3  // ...
4}
  • Resources close in reverse order (out then in).
  • If body throws and close throws, close exceptions may be suppressed (inspect getSuppressed()).

Assertions (concept-level)

1assert x > 0 : "x must be positive";
  • Assertions are disabled by default; enabled with -ea.
  • Don’t use assertions for validating external inputs in production systems.

Concurrency fundamentals

synchronized vs volatile

  • synchronized: mutual exclusion + visibility + happens-before on monitor enter/exit
  • volatile: visibility + ordering for that variable, not atomic compound operations
1volatile int n = 0;
2// n++; // not atomic

Executor basics (concept-level)

1var pool = java.util.concurrent.Executors.newFixedThreadPool(4);
2try {
3  var f = pool.submit(() -> 42);
4  System.out.println(f.get());
5} finally {
6  pool.shutdown();
7}

Concurrency hazards checklist

  • race conditions (shared mutable state without coordination)
  • deadlocks (cyclic lock acquisition)
  • starvation (threads never get resources)
  • visibility bugs (missing happens-before relationships)

I/O and NIO.2 essentials

Path operations

1var p = java.nio.file.Path.of("a", "b", "c.txt");
2var q = p.getParent(); // a/b

Common Files operations

1var p = java.nio.file.Path.of("note.txt");
2var text = java.nio.file.Files.readString(p);
3java.nio.file.Files.writeString(p, text + "\nmore\n");
  • Many operations throw IOException (checked).
  • Watch for encoding assumptions when using bytes vs strings (concept-level).

Directory traversal (concept-level)

1try (var s = java.nio.file.Files.walk(java.nio.file.Path.of("."))) {
2  long count = s.count();
3}

Core APIs worth knowing (concept-level)

java.time type selection

TypeUse when
Instantmachine timestamps, UTC instants
LocalDatedate without time zone
LocalDateTimedate+time without zone
ZonedDateTimeabsolute date+time with zone rules

Localization basics

  • Locale affects formatting/parsing of numbers/dates.
  • ResourceBundle provides localized strings.

Modules (concept-level)

Minimal module-info.java example:

1module com.example.app {
2  requires java.logging;
3  exports com.example.api;
4}
  • exports controls compile-time access for other modules.
  • opens is for deep reflection (frameworks).
  • Classpath vs modulepath differences can show up as missing classes or illegal access.

Final review checklist

  • Rehearse overload resolution with widening/boxing/varargs.
  • Rehearse wildcard rules (what you can add vs read).
  • Rehearse stream return types (Optional vs value vs primitive).
  • Rehearse orElse vs orElseGet.
  • Rehearse try-with-resources close order and suppression.
  • Rehearse equals/hashCode and comparator consistency.

Glossary

TermMeaning
Autoboxing / unboxingAutomatic conversion between primitives and wrapper objects.
Binary numeric promotionRules that promote operands (often to int) before arithmetic.
Capture (lambda)Using a variable from an enclosing scope inside a lambda/inner class.
Covariant returnOverriding method returns a subtype of the original return type.
Erasure (type erasure)Generic type parameters are not retained at runtime in most cases.
Heap pollutionA variable of parameterized type refers to an object not of that parameterized type (often via raw types/varargs).
ImmutabilityObject state cannot change after construction; safer to share across threads.
Invariance (generics)List<A> is not a subtype of List<B> even when A is a subtype of B.
PECS“Producer extends, Consumer super” wildcard rule of thumb.
Short-circuitingOperations that stop early (for example, anyMatch, findFirst).
Suppressed exceptionException thrown during resource close that is attached to the primary exception.
Thread safetyCorrect behavior when code is executed concurrently (no races, proper visibility).
Unmodifiable collectionA collection that throws on structural modification (may be a view).