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.