High-yield 1Z0-829 cheat sheet for Java SE 17: rules, APIs, patterns, and pitfalls across language features, generics, streams, exceptions, and concurrency.
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.
byte + byte becomes int; char participates in numeric promotion; compound assignment can hide casts.== compares references; equals compares content; compile-time constants can be interned.List.of(...), Set.of(...), Map.of(...) are unmodifiable and reject null.IllegalStateException.orElse(...) evaluates eagerly; orElseGet(...) is lazy.volatile gives visibility, not atomicity; synchronized gives mutual exclusion + visibility.Widening conversions (no cast needed):
| From | Can widen to |
|---|---|
byte | short, int, long, float, double |
short | int, long, float, double |
char | int, long, float, double |
int | long, float, double |
long | float, double |
float | double |
Narrowing conversions (cast required, potential truncation/overflow):
1int i = 130;
2byte b = (byte) i; // -126 (overflow)
int first.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;
1byte x = 1;
2x += 200; // compiles (implicit cast), overflow at runtime -> -55
3// x = x + 200; // does not compile (x + 200 is int)
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 is immutable.+ creates new Strings (compiler may optimize compile-time constants).StringBuilder when you’re building in loops.1String s = "a";
2s.concat("b");
3System.out.println(s); // "a" (concat returns new String)
1String json = """
2 {
3 "ok": true
4 }
5 """;
\ at line end.switch statement rulesbyte, short, char, int, their wrappers, enum, and String.case labels must be compile-time constants.break, you fall through (switch statement).switch expressions (Java 14+) basicscase X ->) do not fall through.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};
1outer:
2for (int i = 0; i < 3; i++) {
3 for (int j = 0; j < 3; j++) {
4 if (i == 1) continue outer;
5 }
6}
break label; exits that labeled statement, continue label; continues the labeled loop.When multiple overloads could match, Java prefers (roughly):
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)
1static void g(int... x) {}
2g(); // ok: empty array
3g((int[])null); // ok: x is null (be careful)
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!"
| Modifier | Same class | Same package | Subclass (other package) | Anywhere |
|---|---|---|---|---|
private | ✅ | ❌ | ❌ | ❌ |
| package-private | ✅ | ✅ | ❌ | ❌ |
protected | ✅ | ✅ | ✅ | ❌ |
public | ✅ | ✅ | ✅ | ✅ |
For a new instance:
1class A { A(){ System.out.print("A"); } }
2class B extends A { B(){ System.out.print("B"); } }
3System.out.print(new B()); // prints "AB..."
String[] is an Object[] (compile-time), but assignments can fail at runtime.1Object[] arr = new String[1];
2arr[0] = 42; // ArrayStoreException at runtime
@Override helps catch mistakes1class 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"
public static final.abstract, default, static, and private (Java 9+).If two interfaces provide the same default method signature, the implementing class must override (or pick one via InterfaceName.super.method()).
switch works well with enums; prefer enums for closed sets.1record Point(int x, int y) {}
1record User(String name) {
2 User {
3 if (name == null || name.isBlank()) throw new IllegalArgumentException();
4 }
5}
1sealed interface Shape permits Circle, Rect {}
2final class Circle implements Shape {}
3non-sealed class Rect implements Shape {}
final, sealed, or non-sealed.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).List<Integer> is not a subtype of List<Number>.
| Type | Read | Write |
|---|---|---|
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}
new T() or if (x instanceof T).1java.util.List raw = new java.util.ArrayList<String>();
2raw.add(42); // compiles (warning)
3String s = (String) raw.get(0); // ClassCastException
| Structure | Typical use | Ordering | Allows null | Notes |
|---|---|---|---|---|
ArrayList | fast random access | insertion order | ✅ | resizing array |
LinkedList | deque/queue | insertion order | ✅ | slow random access |
HashSet | membership tests | none | ✅ | uses hashCode/equals |
TreeSet | sorted set | sorted | usually ❌ | comparator/Comparable |
HashMap | key/value lookup | none | ✅ (1 null key) | hashCode/equals |
LinkedHashMap | predictable iteration | insertion/access order | ✅ | LRU caches |
TreeMap | sorted map | sorted by key | usually ❌ | comparator/Comparable |
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 view1var 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]
1int x = 1;
2java.util.function.IntSupplier s = () -> x;
3// x++; // does not compile (x no longer effectively final)
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.
1var out = java.util.stream.Stream.of("a", "bb", "ccc")
2 .filter(s -> s.length() > 1)
3 .map(String::toUpperCase)
4 .toList();
1var s = java.util.stream.Stream.of(1, 2, 3);
2s.count();
3// s.count(); // IllegalStateException
| Operation | Returns |
|---|---|
count() | long |
findFirst() | Optional<T> |
min/max(comparator) | Optional<T> |
allMatch/anyMatch/noneMatch | boolean |
reduce(...) | depends (Optional<T> or T) |
collect(...) | depends (often List, Map, etc.) |
reduce gotchas (concept-level)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"
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
IOException)RuntimeException subclasses (e.g., NullPointerException)Catch more specific exceptions before broader ones.
1try { /* ... */ }
2catch (java.io.FileNotFoundException e) {}
3catch (java.io.IOException e) {}
1try (var in = new java.io.ByteArrayInputStream(new byte[0]);
2 var out = new java.io.ByteArrayOutputStream()) {
3 // ...
4}
out then in).getSuppressed()).1assert x > 0 : "x must be positive";
-ea.synchronized vs volatilesynchronized: mutual exclusion + visibility + happens-before on monitor enter/exitvolatile: visibility + ordering for that variable, not atomic compound operations1volatile int n = 0;
2// n++; // not atomic
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}
1var p = java.nio.file.Path.of("a", "b", "c.txt");
2var q = p.getParent(); // a/b
Files operations1var 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");
IOException (checked).1try (var s = java.nio.file.Files.walk(java.nio.file.Path.of("."))) {
2 long count = s.count();
3}
java.time type selection| Type | Use when |
|---|---|
Instant | machine timestamps, UTC instants |
LocalDate | date without time zone |
LocalDateTime | date+time without zone |
ZonedDateTime | absolute date+time with zone rules |
Locale affects formatting/parsing of numbers/dates.ResourceBundle provides localized strings.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).orElse vs orElseGet.| Term | Meaning |
|---|---|
| Autoboxing / unboxing | Automatic conversion between primitives and wrapper objects. |
| Binary numeric promotion | Rules that promote operands (often to int) before arithmetic. |
| Capture (lambda) | Using a variable from an enclosing scope inside a lambda/inner class. |
| Covariant return | Overriding method returns a subtype of the original return type. |
| Erasure (type erasure) | Generic type parameters are not retained at runtime in most cases. |
| Heap pollution | A variable of parameterized type refers to an object not of that parameterized type (often via raw types/varargs). |
| Immutability | Object 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-circuiting | Operations that stop early (for example, anyMatch, findFirst). |
| Suppressed exception | Exception thrown during resource close that is attached to the primary exception. |
| Thread safety | Correct behavior when code is executed concurrently (no races, proper visibility). |
| Unmodifiable collection | A collection that throws on structural modification (may be a view). |