Java SE 11 Developer cheat sheet
Java SE 11 Developer · Keep the key ideas within reach.
Working with Java Data Types
Primitive sizes: byte 8, short 16, int 32, long 64, char 16 (unsigned), float 32, boolean JVM-dependent (not precisely sized).
Integer literals default to int; a long literal needs L suffix. Binary 0b, octal leading 0, hex 0x, and underscores allowed between digits only (not leading/trailing/next to decimal point).
Numeric promotion: byte→short→int→long→float→double. If either operand is double the result is double; if either is float the result is float; otherwise at least int.
Widening (int→long) is implicit; narrowing (long→int) requires a cast and truncates high-order bits. Casting float/double to int truncates toward zero.
char is numeric: 'a' + 1 yields int 98, so assigning to char needs a cast. String + char concatenates instead of adding.
Local variables must be definitely assigned before use; fields get default values (0, 0.0, false, '\u0000', null).
Wrapper classes are immutable and cached: Integer.valueOf(-128..127) returns cached instances, so == may be true there but false outside the range; use equals for value comparison.
Autoboxing applies in assignment and method calls; unboxing a null wrapper throws NullPointerException.
var (Java 10+) is allowed only for local variables with an initializer; it infers a fixed type and cannot be null-initialized without a target type.
Controlling Program Flow
switch works on byte, short, char, int, their wrappers, String, and enum; long, float, double, and boolean are not permitted.
case labels must be compile-time constants; duplicate labels are a compile error. default may appear anywhere and runs only when no case matches.
Classic switch falls through without break; arrow form (Java 14+) has no fallthrough and can yield a value.
In an if/else chain, only the first true condition executes; conditions must be boolean, not int (unlike C).
for(init; cond; update): all three parts are optional and multiple statements are separated by commas; the scope of init ends with the loop.
Enhanced for over arrays/Iterable uses an iterator or index internally; modifying the collection during iteration throws ConcurrentModificationException.
while checks before the body; do-while checks after, so the body runs at least once.
Labeled break/continue (label:) exits or continues the named outer loop; an unlabeled break exits only the innermost loop or switch.
Short-circuit operators: && and || skip the right operand when the result is already determined; & and | always evaluate both sides.
Java Object-Oriented Approach
An interface method without a body is implicitly public abstract; default and static methods need a body; private interface methods (Java 9+) are allowed for shared helper code.
A class implements multiple interfaces but extends only one class; a subclass constructor calls super() implicitly when no explicit this()/super() call is present.
Overloading is resolved at compile time by parameter types (return type does not count); overriding is resolved at runtime by the actual object type.
Covariant return types are allowed in overrides; private, static, and final methods cannot be overridden, and a static method hides rather than overrides.
An abstract class may have constructors and instance fields; an interface may have only public static final constants.
Access modifiers widen in the order private < package-private < protected < public; protected also grants access to subclasses in other packages.
An inner class holds an implicit reference to its enclosing instance; a static nested class does not.
A final class cannot be extended; a final field must be assigned exactly once (at declaration, in an initializer, or in every constructor).
Polymorphism: a variable of a supertype can reference a subtype object, but only supertype-declared members are accessible without a cast.
Exception Handling and Assertions
Checked exceptions extend Exception but not RuntimeException; they must be caught or declared with throws. Error and RuntimeException are unchecked.
Catch blocks are evaluated in order; a supertype catch before a subtype causes a compile error (unreachable code).
Multi-catch (catch (A | B e)) makes e effectively final and the alternatives must not be related by subclassing.
finally runs even after return or throw, except when System.exit is called or the JVM crashes; a return in finally overrides earlier returns.
try-with-resources closes resources in reverse declaration order; the resource type must implement AutoCloseable; suppressed exceptions are attached to the primary one.
A method that overrides must not add broader checked exceptions than the overridden method declares.
throw takes a Throwable instance; throws declares exception types in a method signature.
Assertions are disabled by default and enabled with -ea (or -enableassertions); assert statements throw AssertionError and must not be used for argument validation.
Exception.getMessage may be null; printStackTrace writes to System.err by default.
Working with Arrays and Collections
Arrays are fixed size with zero-based indices; accessing an invalid index throws ArrayIndexOutOfBoundsException. length is a field, not a method.
Arrays.sort on primitives uses dual-pivot quicksort (not stable); on objects uses TimSort (stable). binarySearch requires a sorted array and returns -(insertion point)-1 when absent.
List.of, Set.of, and Map.of create immutable collections that reject null elements and throw UnsupportedOperationException on modification.
ArrayList resizes dynamically and allows null; LinkedList also implements Deque. HashSet is unordered; LinkedHashSet keeps insertion order; TreeSet is sorted via Comparable/Comparator.
HashMap allows one null key and null values; Hashtable and ConcurrentHashMap do not allow null keys or values.
TreeMap/TreeSet require Comparable keys or a Comparator; otherwise ClassCastException occurs at insertion.
equals and hashCode contracts: equal objects must have equal hash codes; a broken hashCode hides keys in hash-based collections.
The Collection interface does not extend Map; Map is a separate hierarchy. removeIf takes a Predicate and removes matching elements.
Iterator.remove() is the safe way to delete during iteration; calling it before next() throws IllegalStateException.
Working with Streams and Lambda Expressions
Streams are lazy: intermediate operations (filter, map, sorted) do nothing until a terminal operation (collect, forEach, count, reduce) runs.
A stream can be consumed only once; reuse throws IllegalStateException.
Lambda syntax: parameters -> expression, or (parameters) -> { statements; return value; }. A lambda can capture effectively final local variables only.
Method references: Type::staticMethod, instance::method, Type::instanceMethod, and Type::new for constructors.
Functional interfaces have exactly one abstract method; @FunctionalInterface makes extra abstract methods a compile error.
Common functional types: Function<T,R>, BiFunction, Supplier, Consumer, Predicate, UnaryOperator, BinaryOperator.
Primitive streams (IntStream, LongStream, DoubleStream) avoid boxing and provide sum, average, and summaryStatistics.
Collectors: toList, toSet, toMap (duplicate keys throw IllegalStateException unless a merge function is given), groupingBy, partitioningBy, joining.
Optional methods: of, ofNullable, empty, isPresent, ifPresent, orElse, orElseGet, orElseThrow, map, filter; calling get() on an empty Optional throws NoSuchElementException.
Java SE 11 Platform Module System
A module is declared in module-info.java with module com.example { ... }; it must be at the root of the module source tree.
requires declares a dependency; requires transitive re-exports that dependency to modules that read this one.
exports pkg makes a package public to other modules; exports pkg to moduleName restricts it to named modules.
opens pkg allows deep reflection at runtime; opens pkg to moduleName limits it. An open module opens all packages.
A module that does not export a package hides its public types from other modules; the classpath ignores module boundaries.
The unnamed module (classpath) reads all modules; named modules cannot read the unnamed module without --add-reads.
Automatic modules derive their name from the JAR filename; they require all other modules and export all packages.
jdeps analyzes dependencies; jlink builds custom runtime images; jmod handles JMOD files.
uses and provides ... with declare ServiceLoader service consumption and implementation.
Concurrency
Thread states: NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED. start() launches a thread; run() executes on the caller's thread.
Implementing Runnable is preferred over extending Thread; Callable can return a value and throw checked exceptions via Future.
synchronized locks the object's monitor (or the Class object for static methods); wait/notify must be called while holding the monitor, else IllegalMonitorStateException.
volatile guarantees visibility of writes but not atomicity; count++ on a volatile field is still not thread-safe.
AtomicInteger and other java.util.concurrent.atomic classes provide lock-free atomic updates.
ExecutorService.submit returns a Future; get() blocks and throws ExecutionException wrapping the task's exception. shutdown() stops accepting tasks; shutdownNow() interrupts running tasks.
ConcurrentHashMap, CopyOnWriteArrayList, and BlockingQueue implementations are thread-safe; HashMap and ArrayList are not.
Deadlock requires two or more threads each holding a lock the other needs; consistent lock ordering prevents it.
CompletableFuture supports chaining with thenApply, thenCompose, thenAccept, and combining with thenCombine.
Java I/O API
Byte streams (InputStream/OutputStream) handle binary data; character streams (Reader/Writer) handle text with encoding.
Buffered wrappers (BufferedReader, BufferedWriter, BufferedInputStream) reduce physical I/O; BufferedReader.readLine returns null at end of stream.
Files and Paths (java.nio.file) replace java.io.File for most operations: Files.readAllLines, Files.write, Files.copy, Files.move, Files.delete.
Path is not the same as File; Paths.get("a","b") joins segments; resolve appends, relativize computes a relative path.
Files.walk and Files.list return Stream and must be closed (try-with-resources).
Serialization requires implements Serializable; transient and static fields are not serialized; serialVersionUID controls compatibility.
Console readPassword returns char[] to avoid leaving passwords in immutable String objects.
NIO channels and ByteBuffer support non-blocking I/O; FileChannel.transferTo can copy efficiently.
Character encoding: new String(bytes, StandardCharsets.UTF_8); platform default encoding is not guaranteed to be UTF-8.
Secure Coding in Java SE Applications
Never store passwords in String; use char[] and clear it after use to limit exposure in memory and heap dumps.
Use PBKDF2, bcrypt, scrypt, or Argon2 for password hashing; MessageDigest with MD5/SHA-1 alone is not acceptable for passwords.
Prefer SecureRandom over Random for tokens, salts, and keys; Random is predictable.
Prevent SQL injection with PreparedStatement parameters; never concatenate user input into SQL.
Validate and canonicalize input paths before file access to prevent path traversal (../); use Path.normalize and check the resolved path stays within the base directory.
Avoid deserializing untrusted data; use ObjectInputFilter (JEP 290) to restrict allowed classes.
Use TLS with modern protocols and disable weak cipher suites; do not disable certificate validation in production.
Follow the principle of least privilege: run with a SecurityManager (deprecated for removal in later releases) or module restrictions, and limit file/network permissions.
Do not log sensitive data; sanitize log input to prevent log injection.
Localization and Formatting
Locale identifies language and region (e.g., Locale.US, Locale.forLanguageTag("fr-CA")); Locale.getDefault() returns the JVM default.
ResourceBundle.getBundle("messages", locale) loads messages.properties or messages_fr.properties; missing keys throw MissingResourceException.
Property files are ISO-8859-1 by default; use \uXXXX escapes or a UTF-8-aware loader.
NumberFormat.getCurrencyInstance(locale) and getNumberInstance format numbers; DecimalFormat uses patterns like #,##0.00.
DateFormat and SimpleDateFormat are locale-sensitive; SimpleDateFormat is not thread-safe, so prefer DateTimeFormatter.
DateTimeFormatter.ofPattern("yyyy-MM-dd") formats LocalDate; DateTimeFormatter is immutable and thread-safe.
MessageFormat.format("Hello {0}", name) supports positional arguments and choice formats.
Collator compares strings according to locale rules; String.compareTo compares Unicode code points.
TimeZone and ZoneId affect date formatting; use ZoneId.of("America/New_York") rather than raw offsets.
Annotations and Functional Interfaces
@Override, @Deprecated, @SuppressWarnings, and @FunctionalInterface are in java.lang; @Retention, @Target, @Documented, @Inherited are meta-annotations.
RetentionPolicy.SOURCE is discarded by the compiler; CLASS is in the class file but not visible at runtime; RUNTIME is available via reflection.
@Target restricts where an annotation may be applied (TYPE, METHOD, FIELD, PARAMETER, etc.); omitting it allows any location.
Annotation elements are methods with no parameters; defaults are declared with default; allowed types include primitives, String, Class, enums, annotations, and arrays of these.
@FunctionalInterface is optional but causes a compile error if the interface has zero or more than one abstract method.
Default methods and static methods do not count toward the single abstract method requirement.
java.util.function provides Function, Consumer, Supplier, Predicate, and primitive specializations such as IntPredicate and ToIntFunction.
Annotations on parameters are accessible via reflection only if retention is RUNTIME; repeatable annotations require @Repeatable and a container annotation.