Oracle Java SE 21 study materials
Oracle Java SE 21 study resources

Oracle Java SE 21 flashcards

Oracle Java SE 21 · Build recall with a focused review session.

32 cards. Read the term and the definition here. The deck at the top of this page is optional.

LocalDate immutability
java.time.LocalDate is immutable, so plusDays(1) returns a brand-new instance and the original object never changes. This immutability makes the java.time classes thread-safe and freely shareable.
Period versus Duration
Period stores date-based amounts in years, months and days. Duration stores time-based amounts in seconds and nanoseconds. Use Period.between on LocalDate and Duration.between on Instant or time values.
StringBuilder versus StringBuffer
Both are mutable character sequences. StringBuilder is faster and not synchronized, while StringBuffer synchronizes every method and is thread-safe. String itself is immutable, so concatenation in a loop creates many objects.
Autoboxing cache range
Java caches boxed Integer values from -128 to 127, so two autoboxed values inside that range compare equal with ==. Outside the cache, == compares references and is usually false; use equals instead.
Arrow switch fall-through
In a switch statement, arrow labels (case X ->) never fall through and need no break. Colon labels (case X:) fall through into following labels unless a break, return or throw exits the switch.
Switch expression exhaustiveness
A switch expression must cover every possible value, using all enum constants, a default clause, or exhaustive type patterns. It yields a value, and block arms use yield rather than return.
Labeled break and continue
A label placed before a loop lets break label; exit the whole labeled statement and continue label; jump to that loop's next iteration. Labels are how nested loops are controlled precisely.
Covariant return type
An overriding method may declare a return type that is a subtype of the overridden method's return type. It may not reduce visibility or declare broader checked exceptions than the parent method.
Default method conflict
If two implemented interfaces supply the same default method, the class must override it, optionally calling InterfaceName.super.methodName() to select one specific version explicitly.
Sealed class permits clause
A sealed class or interface lists its allowed subtypes in a permits clause. Every permitted subtype must be declared final, sealed, or non-sealed, otherwise compilation fails.
Record compact constructor
Records are implicitly final, their components become final fields, and accessors take the component names. A compact constructor validates or normalizes parameters without repeating the parameter list.
try-with-resources close order
Resources declared in a try-with-resources header close in reverse declaration order. They close even when an exception is thrown, and close failures are attached as suppressed exceptions.
Multi-catch restrictions
In catch (A | B e) the exception types must not be subclasses of one another, and the parameter is implicitly final so it cannot be reassigned inside the catch block.
finally can suppress exceptions
If a finally block executes a return or throws its own exception, it discards any exception propagating from the try or catch blocks. finally also does not run after System.exit.
Array length versus size()
Arrays expose a final length field, strings use the length() method, and collections use size(). Calling length() on an array or size() on a String does not compile.
List.of immutability
List.of, Set.of and Map.of create immutable collections that reject nulls. add, remove, clear and set throw UnsupportedOperationException, although the contained element objects may themselves still be mutable.
ArrayStoreException cause
Arrays are covariant, so a String[] can be assigned to an Object[] reference. Storing a non-String through that reference compiles but throws ArrayStoreException at runtime.
PECS wildcard rule
Use List<? extends T> when you only read elements (a producer) and List<? super T> when you only write elements (a consumer). extends blocks add, while super blocks typed reads.
Streams run once
A stream pipeline can be consumed only once. Invoking a second terminal operation on the same stream object throws IllegalStateException, so a fresh stream must be obtained from the source.
Stream laziness
Intermediate operations such as map and filter are lazy and only build the pipeline. Nothing actually executes until a terminal operation such as collect, forEach or count is invoked.
toMap duplicate key
Collectors.toMap throws IllegalStateException when two elements map to the same key unless a merge function is supplied as the third argument, for example (a, b) -> a.
groupingBy versus partitioningBy
Collectors.groupingBy(classifier) returns Map<K, List<T>> with any number of keys. Collectors.partitioningBy returns Map<Boolean, List<T>> holding exactly two entries: true and false.
Jar manifest Main-Class
java -jar runs the class named by Main-Class in META-INF/MANIFEST.MF. Without that attribute the jar is not executable, and you must use java -cp app.jar fully.qualified.Main instead.
Module requires and exports
module-info.java declares requires for modules it depends on and exports for packages it publishes to other modules. Packages that are not exported stay inaccessible even if their classes are public.
Automatic module naming
A jar placed on the module path without module-info.class becomes an automatic module. Its name is derived from the jar filename unless the manifest sets the Automatic-Module-Name attribute.
start versus run
Calling thread.start() schedules a new thread of execution. Calling run() directly only executes the method body on the current thread with no concurrency, and calling start() twice throws IllegalStateException.
volatile visibility limits
A volatile field guarantees reads see the latest write and prevents reordering, but count++ on a volatile is still not atomic. Use AtomicInteger or synchronized for compound operations.
submit versus execute
ExecutorService.execute takes a Runnable and returns void. submit accepts a Runnable or Callable and returns a Future that can yield a result, surface checked exceptions, or be cancelled.
BufferedReader readLine
BufferedReader.readLine returns the next line without its line terminator, or null at end of stream. It is a character stream, typically wrapping a FileReader or obtained from Files.newBufferedReader.
Files.walk stream closing
Files.walk, Files.list and Files.find return a Stream of Path objects that holds open directory handles. Use try-with-resources to close the stream, otherwise file descriptors leak.
ResultSet cursor position
A ResultSet cursor starts before the first row. Each next() call moves forward one row and returns false once rows are exhausted. Column indexes are 1-based, not 0-based.
executeUpdate return value
Statement.executeUpdate returns the number of affected rows for INSERT, UPDATE or DELETE, and zero for DDL statements. Use executeQuery for SELECT statements that return a ResultSet.