1Z0-771 cheat sheet
1Z0-771 · Keep the key ideas within reach.
Java Fundamentals and Data Types
Primitive widening is automatic and lossless (byte→short→int→long→float→double); narrowing always needs an explicit cast and may truncate.
Integer literals default to int; a long literal needs an L suffix. Floating-point literals default to double; a float literal needs an F suffix.
char is an unsigned 16-bit value; arithmetic on char promotes to int, so char c = 'a' + 1 compiles only with a cast.
Local variables must be definitely assigned before use; fields get default values (0, false, '\u0000', null).
String is immutable; == compares references while equals compares content. The string pool holds compile-time literals only.
Integer caching applies to values -128..127 via Integer.valueOf; == on two autoboxed 200s is false.
var requires an initializer on the same line and cannot be used for fields, method parameters, or null.
Array length is a field (arr.length), String length is a method (s.length()), and List size is a method (list.size()).
Switch expressions with -> do not fall through and must be exhaustive; yield returns a value from a block arm.
Controlling Program Flow and Exception Handling
Checked exceptions extend Exception but not RuntimeException; they must be caught or declared with throws.
catch order must go from most specific to most general; a broader type before a subtype is a compile error.
A multi-catch parameter (catch (A | B e)) is implicitly final and the alternatives cannot be related by subclassing.
try-with-resources closes resources in reverse declaration order; close() is called even when the body throws.
The finally block runs unless the JVM exits (System.exit) or the thread is killed; a return in finally overrides earlier returns.
Overriding methods may narrow or drop checked exceptions but never add broader checked exceptions.
assert statements are disabled by default and must be enabled with -ea; they throw AssertionError, not Exception.
Labels (outer:) allow break/continue to target an enclosing loop; an unlabeled break exits only the innermost loop.
The enhanced for loop cannot modify the underlying collection structurally while iterating without a ConcurrentModificationException.
Object-Oriented Programming: Classes, Inheritance, Interfaces, and Records
A record is implicitly final, its components are private final fields, and it gets a canonical constructor plus equals, hashCode, and toString.
A compact canonical constructor in a record omits the parameter list and cannot assign fields directly; it assigns via the implicit parameters.
Interfaces may declare default, static, and private methods; fields are implicitly public static final.
A class implementing two interfaces with the same default method must override it or the code fails to compile.
Constructors are not inherited; super() or this() must be the first statement if present.
Static methods are hidden, not overridden; instance fields are hidden, so polymorphic access uses the declared type.
An abstract class may have zero abstract methods; a class with any abstract method must be abstract.
Sealed classes use permits and subclasses must be final, sealed, or non-sealed; permits can be omitted if subclasses are in the same file.
Objects.equals and Objects.hashCode are null-safe helpers; overriding equals requires overriding hashCode.
Generics and Collections
Generics are erased at compile time; you cannot use primitives as type arguments or do new T() or instanceof List.
List<? extends Number> is a read-only producer; List<? super Integer> is a write-only consumer (PECS).
ArrayList is backed by an array with O(1) random access; LinkedList has O(1) add/remove at ends but O(n) get.
HashMap allows one null key and multiple null values; Hashtable and ConcurrentHashMap disallow null keys or values.
TreeMap and TreeSet are sorted by natural ordering or a Comparator and use compareTo, not equals, for key identity.
LinkedHashMap preserves insertion order; access-order mode plus removeEldestEntry builds an LRU cache.
The Collections utility class provides unmodifiableList, synchronizedList, and sort; List.of returns an immutable list.
A Comparator can be composed with thenComparing, reversed, and comparing; nullsFirst/nullsLast handle null elements.
Iterating a collection and structurally modifying it (other than via the iterator) throws ConcurrentModificationException.
Lambdas, Streams, and Functional Interfaces
A functional interface has exactly one abstract method; @FunctionalInterface is optional but checked by the compiler.
Core functional interfaces: Function<T,R>, BiFunction, Supplier, Consumer, Predicate, UnaryOperator, and their primitive variants.
Stream operations split into intermediate (lazy: map, filter, sorted) and terminal (eager: collect, forEach, reduce, count).
Streams are single-use; reusing a consumed stream throws IllegalStateException.
collect(Collectors.groupingBy) returns Map<K, List>; partitioningBy always returns a two-entry map with true and false keys.
Optional.map transforms the value if present; orElse always evaluates its argument while orElseGet is lazy.
Parallel streams use the common ForkJoinPool; they help only with large, CPU-bound, splittable workloads.
Method references: Class::staticMethod, instance::method, Class::instanceMethod, and Class::new for constructors.
Concurrency and Multithreading
Thread states: NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED; getState() returns these values.
start() creates a new thread of execution; calling run() directly executes on the current thread.
synchronized locks the object's monitor; static synchronized locks the Class object.
wait(), notify(), and notifyAll() must be called while holding the object's monitor, else IllegalMonitorStateException.
volatile guarantees visibility and ordering but not atomicity; count++ on a volatile int is still unsafe.
AtomicInteger uses compareAndSet; incrementAndGet is atomic without locking.
ExecutorService.submit returns a Future; shutdown() stops accepting tasks while shutdownNow() interrupts running ones.
A deadlock needs two or more threads each holding a lock the other needs; consistent lock ordering prevents it.
CompletableFuture supports chaining with thenApply, thenCompose, and thenCombine, and async variants run on a pool.
I/O, NIO.2, and Serialization
java.io streams are byte-based (InputStream/OutputStream) or character-based (Reader/Writer); wrap with BufferedReader for performance.
BufferedReader.readLine returns null at end of stream; closing a wrapper closes the underlying stream.
Files.newBufferedReader(path) and Files.readAllLines(path) are the NIO.2 replacements for FileReader patterns.
Path is the abstraction for a location; Paths.get or Path.of creates one, and Files.exists checks it.
Files.walk is a lazy depth-first stream; Files.walkFileTree requires a FileVisitor for explicit control.
Serialization requires implements Serializable; serialVersionUID guards version compatibility, and transient fields are skipped.
Externalizable requires a public no-arg constructor and manual writeExternal/readExternal implementations.
Files.move with StandardCopyOption.ATOMIC_MOVE fails if the target exists unless REPLACE_EXISTING is also given.
WatchService registers directories for ENTRY_CREATE, ENTRY_MODIFY, and ENTRY_DELETE events.
Modules and the Module System
module-info.java declares requires, exports, opens, uses, and provides directives; it must be at the source root.
A module exports packages, not classes; unexported packages are inaccessible even with reflection unless the module is opened.
requires transitive re-exports a dependency to modules that read yours; plain requires does not.
opens allows deep reflection at runtime; opens ... to limits it to named modules.
The unnamed module reads all other modules; automatic modules (plain JARs on the module path) export all packages.
jlink creates a custom runtime image; jdeps analyzes dependencies; jmod handles .jmod files.
--add-modules and --add-opens are command-line workarounds for missing requires or opens.
ServiceLoader loads implementations declared with provides ... with ...; the consumer declares uses.
Split packages across two named modules are forbidden; the class path tolerates them, the module path does not.
Annotations, Reflection, and Date/Time API
@Retention controls visibility: SOURCE (compiler only), CLASS (default, in bytecode), RUNTIME (reflection-visible).
@Target lists applicable element types; omitting it means any declaration is allowed.
A custom annotation is declared with @interface and its elements are methods with no parameters, optionally with defaults.
Annotations are accessed via getAnnotation(Class) or getAnnotationsByType for repeatable annotations.
Class.forName loads and initializes a class; ClassLoader.loadClass loads without initializing.
getDeclaredMethods returns all methods of the class including private ones but excluding inherited ones; getMethods returns public only, including inherited.
setAccessible(true) bypasses access checks but may be denied by the module system unless the package is opened.
LocalDate, LocalTime, and LocalDateTime are immutable; LocalDateTime has no zone, so use ZonedDateTime or Instant for absolute time.
DateTimeFormatter is immutable and thread-safe; ofPattern uses letters like yyyy, MM, dd, HH, mm.
Period is date-based (years/months/days); Duration is time-based (seconds/nanos).