
Explore the evolution of Java from nine to seventeen, focusing on productivity, memory footprint improvements, faster startup, and tools that enhance performance and reliability.
Explore Java releases from nine to seventeen, including the module system, local variable type inference, text blocks, switch expressions, sealed classes, and migration tools, with practical examples and exercises.
Students will get an understanding of the Java release schedule. There are a few changes recently announced, which we will look at in another lecture.
Choose OpenJDK for free, open source Java with GPL v2 plus classpath exception, while Oracle JDK shifts to a paid production license after Java 11.
Java 17 announces an lts update and a no-fee license, proposing a two-year lts cadence with six-month releases, granting free use for article JDK 17 and beyond for one year.
1. The java_catching_up zip file contains source code that we will refer to throughout the course.
2. The modules_movieflix.zip and multi_modules.zip contain source code that we will refer to when we discuss modules, this is in the next section when we explore Java 9.
3. The JMH_Demo.zip contains source code that we will look at in Section 5 when we explore Java 12 and the concept of JMH.
Explore JDK nine features including collection factory methods, G1 garbage collector basics, compact strings and indefi string concatenation, the modular system with Jlink and Jshell, and stream API enhancements.
Explore creating unmodifiable collections in Java 8 and Java 9 with List.of, Set.of, and Map.of, and learn when Map.ofEntries applies.
Explore the off method for lists, sets, and maps, including unmodifiable results, no null elements, and duplicate handling with exceptions, plus space-efficient behind-the-scenes implementations.
Explore the difference between Collections.unmodifiableList as an unmodifiable view and List.of as a true unmodifiable list, including backing collection mutability and null handling.
Explore how the G1 collector partitions the heap into eden, survivor, and old regions, evacuating eden via young collections and triggering a concurrent mark cycle at 45%.
Compact strings in JDK nine switch string data from a char array to a byte array and introduce a private byte coder field, enabling on-construction compression.
Explore the indefi string concatenation feature and how Java nine translates plus to StringBuilder appends, the role of invokedynamic in Java nine, and runtime strategies for faster, memory efficient concatenation.
Declare module dependencies with requires to access other modules, such as java.logging, and export packages to enable the movie recommendation controller to log messages at runtime.
Learn why automatic modules matter when migrating from jar files to modules, enabling explicit dependencies via module path and allowing automatic modules to read all modules and export packages.
Explore named, unnamed, and automatic modules in Java, learn how to run from the module path versus the classpath, and understand how legacy jars become explicit or automatic modules.
Enable reliable configuration by declaring module dependencies, allowing compile-time and launch-time analysis that fail fast on missing modules, while enforcing strong encapsulation and exporting only selected functionality for scalability.
Understand how Java 9 modularization encapsulates internal APIs, causing access barriers to sun.security.x509, and use the Java Dependency Analysis Tool to surface internal dependencies and replace with standard APIs.
Learn how Jlink, the Java linker, builds a tailored runtime image containing only the modules your application needs, reducing size and improving startup time.
Learn to use jlink to build a custom runtime image for a modular application with a single module, including only the required modules.
Learn to use jlink to build a custom runtime image that includes two modules, managing module path and dependencies from a mods folder and producing a lean, runnable application.
Explore jshell, the read-evaluate-print loop bundled with the JDK since Java 9, for interactive Java snippets. Prototype and get immediate feedback, since jshell is not an IDE.
Explore jshell commands and features for prototyping Java code, including lambda expressions and method references, with saving, opening, editing, listing, and help, and immediate feedback without a class setup.
Explore how private methods in interfaces, introduced in Java 9, reduce duplication by refactoring common logic from default methods, while preserving interface evolution and encapsulation.
Learn how the takewhile method in the stream API extracts stock names with values of 500 or less from a sorted list, short-circuiting when a predicate fails, unlike filter.
Explore how dropWhile processes a sorted stock list to remove values 500 or less and return stocks over 500, and compare it with takeWhile and filter.
Explore Java 9 stream iterate overload with a predicate to produce and terminate streams using seed, predicate, and unary operator, and learn takewhile with primitive streams.
This lecture includes a downloadable PDF guide that introduces the Flow API, a powerful feature added in Java 9 to support reactive programming.
What you’ll find inside:
- A clear explanation of the Flow API and why it was introduced
- The four core interfaces: Publisher, Subscriber, Subscription, and Processor
- Practical examples using `SubmissionPublisher`
- How the Flow API connects with libraries like RxJava and Project Reactor
- Key takeaways to help you build a strong foundation for modern Java development
Even though you may not use the Flow API directly in day-to-day coding, it provides the foundation for many reactive libraries and frameworks.
Download this PDF and keep it as a handy reference — it will strengthen your understanding of Java’s evolution and help you in both learning and interviews.
Explore local variable type inference and the or else throw method in optional. Learn to create unmodifiable collections and enable application class data sharing to improve startup time on docker.
Learn where local variable type inference with var can be used (initializers, for loop indices, try-with-resources) and where it cannot (fields, method parameters, return types, catch blocks).
Explains local variable type inference using var, showing when it improves readability and when it can hinder understanding, with concrete examples on for loops, maps, and literals.
Harness local variable type inference with var to simplify a stream-based approach that groups by movie name, finds the most watched movie, and refactors for readability.
Explore the orElseThrow method in the Optional class, introduced in JDK ten, to return a value or throw NoSuchElementException. See why get can mislead and orElseThrow improves readability over isPresent.
Learn how the copyOf method creates unmodifiable lists, sets, and maps, providing immutability and a read-only view into the original data.
Investigate how the JVM now recognizes Docker container constraints via cgroup settings to adjust heap and memory usage, with backport fixes to Java 8 update 191.
Explore Java 11 features, including the Http client with Http2 and WebSocket non-blocking semantics, local variable syntax for lambda parameters, and new string methods like repeat, isBlank, strip, and lines.
Explore the Java http client API introduced in JDK 11 and compare it with the legacy HTTP URL connection, highlighting its fluent, asynchronous design with HTTP/2 and reactive streams integration.
Learn local variable type inference for lambda parameters using var, enabling annotations on parameters and aligning with local variable syntax introduced in JDK 10 and extended in JDK 11.
Discover how the string API repeat method in JDK 11 repeats a string n times and returns an empty string for zero, using a byte array and System.arraycopy.
Learn how the strip method handles unicode whitespace in java, using character.isWhitespace, and compare it with strip trailing, strip leading, and the traditional trim behavior.
Demonstrate the difference between trim and strip on a text with whitespace, showing trim returns length 11 while strip returns 5, and illustrate strip trailing and leading variants.
Explore the epsilon garbage collector, a no-op GC that does not reclaim memory. Use it for performance analysis, memory pressure testing, and ultra latency sensitive applications.
Understand how JDK 11 removes Java EE modules such as Jax-ws, JAXB, and Corba, and what this means for migrating apps that rely on these APIs.
Analyze why applets and browser plugins faced security risks and were phased out, with Nashorn deprecated in JDK 11. Consider GraalVM JavaScript as the modern alternative on the JVM.
Analyze deprecation of JavaFX and OpenJFX as an open-source project, while Java is no longer bundled in JDK 11+ and modules are fetched via Maven Central with Maven or Gradle.
Explore the readString and writeString methods in the files class (JDK 11) to read a file into a string and write string content.
Explains how the not method in the predicate interface improves readability by filtering non-blank lines from a file using streams, method references, and optional type casting.
Explore JDK mission control, an open source tool for monitoring, profiling, and troubleshooting Java applications in production, with JFR flight recordings, real-time VM analysis, and automated diagnostics.
Learn how to use the JDK mission control user interface to connect to a Java program, view live statistics, and diagnose a deadlocked multithread scenario.
Start a flight recording with java -X:StartFlightRecording, dump on exit, or jfr start with the pid, then stop to dump, and view thread dumps and deadlock in Mission Control UI.
Explore compact number formatting in Java using CompactNumberFormat to display numbers in short forms like 1 k, 100 M, or 1 B, with locale awareness and rounding options for UI.
Learn how the teeing collector merges two downstream collectors to process a stream in parallel, using joining and counting to produce a sentence and its total word count.
Explore the Files API mismatch method in JDK 12, which compares two files and returns -1 for identical content, or the first mismatched byte index, or the smaller file size.
Explore preview features in Java with switch expressions from JDK 12. Learn how to enable previews, compile and run, and see how switch expressions improve readability.
Shenandoah, introduced in Java 12, reduces GC pause times by evacuating concurrently. It uses a forwarding pointer, or brooks pointer, to relocate objects without stopping the program.
Explore the string.indent method added in jdk eight, indenting every line by a given number of spaces; see examples with a poem and a json string, including negative values.
Use the string class transform method to drop the first word, uppercase each remaining word’s first letter, and append three dots. Compare two solutions and highlight a fluent, functional approach.
Micro benchmarking is hard; leverage the Java Microbenchmark Harness (JMH) for reliable results, then use profilers for insights in latency-sensitive or library development work.
Explore JDK 13 changes, including reimplemented legacy socket API, dynamic archives for application class data sharing, text blocks, new string methods, and switch expression and Z garbage collector enhancements.
Explore text blocks, a JDK 13 preview feature using three double quotes as opening and closing delimiters to simplify multi-line strings, with plans for permanence in Java 15.
Explore how the stripIndent method in JDK 13 cleans incidental whitespace from multi-line strings, preserving the intended indentation via text blocks and the string lines method.
Apply the translate escapes method to convert escape sequences in external file lines into proper strings, then group non-blank lines by length and present translated results.
Explore string interpolation and how the static format method and the instance formatted method format strings, including text blocks, and how strip indent and translate escapes enhance readability.
Explore switch expressions and their evolution from JDK 12 preview to JDK 14 permanent feature, noting the yield keyword introduced in JDK 13 and switch as an expression.
Explore how the z garbage collector enhancements in Java 13 return uncommitted heap memory to the operating system, shrinking the heap and improving performance.
Explore Java 14 features like switch expressions and helpful null pointer exceptions, and review changes in garbage collection. Learn about records for concise data declarations and pattern matching.
Compare traditional switch statements with Java's modern switch expressions, now a standard feature since Java 14. Learn about arrows, no breaks, default cases, and value assignment.
Explore vintage switch statements versus modern switch expressions, featuring arrow labels, comma-separated cases, and yielding values, while noting mixing label styles is not allowed.
Records provide a compact syntax for lean data carrier classes, reducing boilerplate and enabling immutable data with auto generated methods. A compact constructor supports validation.
Explore pattern matching for instanceof in JDK 14, which combines type testing and binding into a step, reducing boilerplate and casting, with a preview status and future switch expression use.
Explore changes in JDK 15 such as text blocks and compile-time processing, review null pointer exceptions improvements, and survey records, local records, sealed classes and interfaces, and garbage collector changes.
Learn how text blocks, permanent since JDK 15, implement multi-line strings, compare them with traditional literals, and identify when to use text blocks for readability.
Explore text blocks in Java and learn two escape sequences: the line terminator to suppress a newline and the explicit space escape sequence to preserve trailing spaces.
Explore how text blocks are compiled: normalize line terminators, strip incidental whitespace, and interpret escapes. Use text blocks to improve readability, and reserve traditional literals for short, single-line strings.
Explore helpful null pointer exceptions that pinpoint the exact null, such as address in customer, with plus show code details, Java 14, and default in Java 15; disable with minus.
Refactor plain data wrappers into records to cut boilerplate and rely on compiler-generated equals, hashCode, toString, and immutable data carriers with accessors for name, latitude, and longitude.
See how a local record, defined inside a method, aggregates a movie and its score to produce the top three via a stream pipeline.
Examine how sealed classes constrain extensibility by listing permitted subclasses, with examples like payment, cash payment, and card payment, and contrast sealed, non-sealed, and final modifiers for secure, well-typed hierarchies.
Explore JDK 15 changes, including the GCC garbage collector becoming a permanent feature with max heap up to 16 TB and Shenandoah moving to product status as G1 remains default.
Use records to return multiple values in a single pass, demonstrated by min and max gross earning movies via a min-max record, comparator, and downstream collectors.
Explore how records serve as data transfer objects and return multiple values, a min-max movie example, and note their use in stream operations and as compound map keys.
Explains how to use the stream flatMap to extract the cast from Martin Scorsese movies, showing a one-to-many transformation and flattening into a single list, contrasting with map.
Discover map multi, a JDK 16 stream method for one-to-many transformations with a single flattened stream, unlike flatMap, and learn when an imperative approach suits emission of movie cast.
Refactor mapMulti by explicit types or a consumer, using a method reference for getStar. Use toList in JDK 16 to yield an unmodifiable list rather than collect.
Delve into pattern matching for instanceof, the type pattern feature now permanent in Java 16, and refactor code to bind values with a pattern variable while eliminating casting boilerplate.
Explore pattern matching for instanceof, showing how binding variables gain scope within control flow and how a phone number equals method can be refactored into a concise type-pattern check.
Explore how pattern matching evolves beyond instanceof, enabling switch expressions and case labels, deconstruction of records, and array patterns to write clearer, type-safe code.
Design an expression system with sealed types and records, using constant, add, multiply, and negate to implement evaluate logic.
Learn how jpackage packages self-contained Java applications, bundling jars with the runtime to produce installable bundles (MSI, DMG, deb, rpm) for Windows, macOS, and Linux, with no cross-platform deployment.
Discover how Java 16 introduces value-based classes and deprecates public constructors of primitive wrappers in favor of factory methods. Understand the Valhalla motivation and synchronization warnings on value-based instances.
Explore JDK 17, a long-term support release, highlighting strong encapsulation of internal APIs and new classes, interfaces, and enums. Discover pattern matching for switch, yielding concise case labels.
Explain how sealed classes let you control permitted subtypes, enabling secure hierarchies and accurate domain modeling while highlighting compile-time checks on conversions.
Explore how strong encapsulation of JDK internals tightens security and maintainability in JDK 17, moving developers toward standard APIs and away from internal elements, with warnings and exceptions guiding migration.
Explore the removals and deprecations in Java 17, including the legacy security manager deprecated for removal, the applet API deprecated for removal, and the removal of the RMI activation mechanism.
Explore pattern matching for switch as a preview in JDK 16 and beyond, using type patterns, guarded patterns, and null-aware cases to simplify switch expressions and improve readability.
Java has changed more since Java 9 than at any time in its history. From modules and `var` to records, sealed classes, text blocks, and switch expressions — the language is evolving fast, and keeping up can be a challenge.
This course gives you a step-by-step path from Java 9 through Java 17, making it simple to catch up with all the modern features while building confidence through hands-on exercises.
By the end of this course, you will:
Understand how Java has evolved beyond Java 8
Master new language features like modules, var, records, sealed classes, text blocks, and switch expressions
Explore new garbage collectors, library enhancements, tools, and deprecations
Learn how the new JDK release cycle impacts developers
Gain confidence with practical exercises and solutions
Be better prepared for interviews and real-world projects
Starting from Java 9, we will incrementally move up to Java 17 and explore :
Language Features, Garbage Collectors, Library enhancements, Tools, Removals and Deprecations, and a lot more.
We target a single Java release in every section.
Some of the topics covered -
Text Blocks, Switch Expressions, Records, Pattern Matching for instanceof, Pattern Matching for switch, Sealed Classes
Garbage Collectors - G1, Epsilon, ZGC, Shenandoah
Modularity, jdeps, jlink, jdeprscan
Improved Docker Container Detection
Tool/Toolkit - Jpackage, JShell, JDK Flight Recorder
Factory methods in Collections
Compact Strings
Understand how String concatenation works behind the scenes
Some of the changes in the Stream API
Local Variable Type Inference along with recommendations on usage
Application Class Data Sharing
The new HTTP Client API
Handy String API changes
Writing scripts using the Java programming language
Teeing Collector
JMH (Java Microbenchmark Harness)
Encapsulated JDK internals
Tips on Migration (Examples on JAXB, Hibernate, and Spring Boot)
and more!
Now includes a downloadable PDF guide on the Java Flow API (Java 9+) — a beginner-friendly reference that explains the core reactive programming interfaces with clear examples and key takeaways. This bonus resource strengthens your understanding and helps with interview preparation.
The course will immensely benefit Java developers interested in getting up to speed with the ever-evolving Java language.
There are lots of exercises (along with the solution) that will help you to gain confidence.
The course is not a migration guide but we do cover numerous areas that can have an impact on migration.
What if you have questions?
I offer full support, 7 days a week, answering any questions you have.