Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Old Dog, New Tricks: The Java 25 Reinvention - ...

Old Dog, New Tricks: The Java 25 Reinvention - JNation

Modern Java has evolved into a powerful, expressive language by quietly adopting the best ideas from its peers without compromising its core principles of readability, safety, and performance. In this talk, we'll explore how Java 25 now competes head-to-head with languages like Kotlin, Scala, Rust, and Go.

- Pattern Matching that's as expressive as Scala and Rust
- Virtual Threads, Java's lightweight concurrency mode, inspired by goroutines
- Structured Concurrency for safer, more predictable parallel programming
- Records for concise and immutable data modelling, akin to Kotlin's data classes
- Foreign Function & Memory API as a modern, safer alternative to JNI, rivalling Rust’s FFI

If you’ve ever dismissed Java as too verbose or outdated, this session will change your mind. See how Java 25 isn’t just catching up; it’s redefining what modern Java can be.

Avatar for A N M Bazlur Rahman

A N M Bazlur Rahman

May 24, 2026

More Decks by A N M Bazlur Rahman

Other Decks in Programming

Transcript

  1. https://bazlur.ca A N M Bazlur Rahman @bazlur_rahman Old Dog, New

    Tricks The Java 25 Reinvention JAVA 25 • RE:INVENTED
  2. https://bazlur.ca A N M Bazlur Rahman @bazlur_rahman AI Changed the

    Cost of Code 2 Code generation is getting cheap. Understanding code is getting expensive. AI produces code faster than teams can fully validate it. Production software still demands: correctness maintainability security debuggability operational safety human judgment The bottleneck has moved from writing code to trusting code.
  3. https://bazlur.ca A N M Bazlur Rahman @bazlur_rahman AI Writes. Humans

    Decide. 3 AI WRITES scaffolding boilerplate first drafts refactor suggestions suggested tests HUMANS DECIDE design judgment code review architecture trade-offs failure modes production incidents long-term maintenance A modern programming language should help humans reason.
  4. https://bazlur.ca A N M Bazlur Rahman @bazlur_rahman The Hallway Track

    Buzz “Java's so verbose. A simple data class is 50 lines of boilerplate.” “We moved our I/O-heavy services to Go for the concurrency model.” “Java feels like it's always playing catch-up with languages like Kotlin.” “Why deal with JNI? We just use Rust when we need to call native code.” 4
  5. https://bazlur.ca A N M Bazlur Rahman @bazlur_rahman When Code Is

    Cheap, Trust Becomes the Product Is Java merely reacting? Or has Java been reinventing for exactly this moment? 5 T HE QU E ST ION
  6. https://bazlur.ca A N M Bazlur Rahman @bazlur_rahman Closing the Expressiveness

    Gap T H E N 6 N O W records → data carriers without boilerplate sealed types → closed hierarchies you can reason about pattern matching → safer, clearer branching Modern Java removes the friction between thought and code. final class Person { private final String name; private final int age; Person(String name, int age) { ... } String name() { return name; } int age() { return age; } public boolean equals(Object o) { ... } public int hashCode() { ... } public String toString() { ... } } Ceremony over intent
  7. https://bazlur.ca A N M Bazlur Rahman @bazlur_rahman The Universal Challenge:

    Modeling Data with Multiple States T H E B R I T T LE I N S T A N C E O F L A D D E R T H E W E A K N E S S E S 7 double area(Object o) { if (o instanceof Circle) { Circle c = (Circle) o; if (c.radius() <= 0) { throw new IllegalStateException(); } return Math.PI * c.radius() * c.radius(); } else if (o instanceof Rectangle) { Rectangle r = (Rectangle) o; if (r.w() <= 0 || r.h() <= 0) { throw new IllegalStateException(); } return r.w() * r.h(); …… } No Compiler Guarantees Add a new Shape and the compiler stays silent. Verbose & Error-Prone Manual casting invites ClassCastException at runtime. Unstructured Logic Business logic scatters across nested branches. Modern languages solve this with a unified pattern: Algebraic Data Types.
  8. https://bazlur.ca A N M Bazlur Rahman @bazlur_rahman Scala's Approach: Expressiveness

    with Sealed Hierarchies S U M & P R O D U CT T YP E S E X H A U S T I V E P A T T E R N M A T C H IN G 8 sealed trait Shape case class Circle(radius: Double) extends Shape case class Square(side: Double) extends Shape sealed trait: A closed set of types, known at compile time. case class: A concise, immutable data carrier (product type). def getArea(s: Shape): Double = s match { case Circle(r) => math.Pi * r * r case Square(s) => s * s } case Circle(r): Matches the type and deconstructs the data in one step. Sealed hierarchies + pattern matching = compile-time safety with no boilerplate.
  9. https://bazlur.ca A N M Bazlur Rahman @bazlur_rahman Kotlin’s Approach: Pragmatism

    with Sealed Classes S U M & P R O D U CT T YP E S E X H A U S T I V E P A T T E R N M A T C H IN G 9 sealed class Shape data class Circle(val radius: Double) : Shape() data class Square(val side: Double) : Shape() sealed class: Restricts inheritance, creating a known, finite hierarchy. data class: Auto-generates boilerplate for data-centric classes. fun getArea(s: Shape): Double = when (s) { is Circle -> Math.PI * s.radius * s.radius is Square -> s.side * s.side } is Circle: Type check with smart cast; no else needed; exhaustive. Pragmatic syntax for ADTs and exhaustive matching. Concise where it counts.
  10. https://bazlur.ca A N M Bazlur Rahman @bazlur_rahman Rust’s Approach: Uncompromising

    Safety with Enums S U M & P R O D U CT T YP E S E X H A U S T I V E P A T T E R N M A T C H IN G 10 enum Shape { Circle { radius: f64 }, Square { side: f64 }, } enum: A true sum type where each variant can carry its own data. Variants can hold struct-like or tuple- like data. fn area(s: Shape) -> f64 { match s { Shape::Circle { radius: r } => PI*r*r, Shape::Square { side: s } => s*s, } } • Matches the variant and binds its fields to local variables. • Exhaustiveness is enforced at compile time. Rust enforces correctness at the type level. No invalid states, no runtime surprises.
  11. https://bazlur.ca A N M Bazlur Rahman @bazlur_rahman Java’s Solution: A

    Familiar Syntax for a Modern Pattern S U M & P R O D U CT T YP E S E X H A U S T I V E P A T T E R N M A T C H IN G 11 sealed interface Shape permits Circle, Square {} record Circle(double radius) implements Shape {} record Square(double side)implements Shape {} Defines a closed hierarchy with an explicit permits clause. record: An immutable, transparent carrier for data. double getArea(Shape s) { return switch (s) { case Circle(var r) -> Math.PI*r*r; case Square(var s) -> s*s; }; } • Type pattern deconstructs the record, binding components. • Exhaustiveness checked at compile time. Familiar syntax, modern guarantees. Java now expresses ADTs as cleanly as Scala, Kotlin, or Rust.
  12. https://bazlur.ca A N M Bazlur Rahman @bazlur_rahman The Core Guarantee:

    Compiler-Enforced Completeness 12 Feature Scala Kotlin Rust Java Sealing Mechanism sealed keyword (same file) sealed class / sealed interface (same module) enum is inherently closed sealed with permits clause Missing Case (compile time) Warning (by default) Error (for when expressions) Error (non- negotiable) Error (for switch expressions) Add New Variant (runtime) MatchError exception NoWhenBranch MatchedException N/A (forces recompile) MatchException (fail-fast) Null Handling Throws MatchError Explicit null branch required Impossible (uses Option<T>) Explicit case null -> pattern The crucial outcome is the same: adding a new data variant turns a potential runtime bug into a compile- time check, making refactoring safe.
  13. https://bazlur.ca A N M Bazlur Rahman @bazlur_rahman The Payoff: Readability

    and Fearless Refactoring 13 • When the data model evolves, the compiler becomes your guide. • Every switch expression that needs an update is flagged as a compile-time error, not a silent runtime bug. • This scales maintainability: you can change core data types with confidence. Refactor without fear: the compiler points to every place that needs your attention.
  14. https://bazlur.ca A N M Bazlur Rahman @bazlur_rahman But what about

    performance and scale? Language expressiveness is one half of the story. The other half is how we run our code. 15 THE NEXT QUESTION Java 21+ rewrote the runtime, and it changes everything.
  15. https://bazlur.ca A N M Bazlur Rahman @bazlur_rahman The Concurrency Dilemma

    We Lived With 16 Scalability Wall Complexity Trap Thread-per-Request Simple & debuggable, but doesn’t scale Async / Reactive Scales, but hard to maintain You were forced to choose: simple code that didn’t scale, or scalable code that was hard to maintain.
  16. https://bazlur.ca A N M Bazlur Rahman @bazlur_rahman The Solution: Lightweight

    Threads Managed by the JVM 17 Go Goroutines go myFunction() Java Virtual Thread Thread.startVirtualThread(this::myFunction); Virtual Threads OS Threads The programming model, the APIs, and the debugging tools you already know continue to work seamlessly. Executors.newVirtualThreadPerTaskExecutor() Write blocking code. Get async scale. No new mental model required.
  17. https://bazlur.ca A N M Bazlur Rahman @bazlur_rahman Scale Is Solved:

    But What About Safety? 18 T HE “ O R PH AN E D TA SK ” PR O B LE M FAIL t=0 t=1 t=2 t=3 Orphaned tasks. They continue running in the background, consuming resources, holding connections, and polluting logs, even though their results will never be used. // What happens if profile.get() throws an exception? Future<Profile> profile = executor.submit(this::fetchProfile); Future<Preference> prefs = executor.submit(this::fetchPrefs); // This keeps running... Future<Risk> risk = executor.submit(this::fetchRisk); // ...and so does this. Profile p = profile.get(); // Exception! Concurrency works, but errors and cancellation leak across tasks. We solved scale, not safety.
  18. https://bazlur.ca A N M Bazlur Rahman @bazlur_rahman Structured Concurrency: If

    the Parent Fails, the Children Die 19 P A T T E R N # 1 : A L L - O R - N O T H I N G P A T T E R N # 2 : FI R S T - W IN Use Case: Get results from multiple services to build a response. Use Case: Racing multiple redundant services for the fastest response. try (var scope = StructuredTaskScope.open()) { var profile = scope.fork(this::fetchProfile); var prefs = scope.fork(this::fetchPrefs); scope.join(); // wait for all, or fail fast } try (var scope = StructuredTaskScope.open( Joiner.<String>anySuccessfulResultOrThrow())) { scope.fork(() -> fetchFromMirror("mirror-1")); scope.fork(() -> fetchFromMirror("mirror-2")); String fastest = scope.join(); // losers cancelled } FAIL ⊗ CANCELLED ⊗ CANCELLED ✓ SUCCESS ⊗ CANCELLED ⊗ CANCELLED Failures and successes propagate cleanly: siblings are cancelled, resources are reclaimed, lifetimes are bounded.
  19. https://bazlur.ca A N M Bazlur Rahman @bazlur_rahman JNI: The Necessary

    Evil Is No Longer Necessary 21 For decades, integrating native C/C++ libraries meant using JNI. Complex Unsafe Brittle JNI was the single biggest pain point for Java applications needing high-performance or systems-level capabilities (AI/ML, low-level I/O). Foreign Function & Memory API replaces JNI: safe, expressive, and 100% Java.
  20. https://bazlur.ca A N M Bazlur Rahman @bazlur_rahman Native Interop: Reimagined

    22 Project Panama provides a safe, pure Java alternative through the Foreign Function & Memory API. Linker linker = Linker.nativeLinker(); SymbolLookup libc = linker.defaultLookup(); MethodHandle strlen = linker.downcallHandle(...); try (Arena arena = Arena.ofConfined()) { MemorySegment str = arena.allocateFrom("Hello FFM"); long len = (long) strlen.invoke(str); } A first-class Java feature: strong safety, improved ergonomics, approaching Rust’s FFI.
  21. https://bazlur.ca A N M Bazlur Rahman @bazlur_rahman DEMO 23 LI

    VE CO DE Java that breathes: sealed types, pattern matching, virtual threads, structured concurrency, FFM.
  22. https://bazlur.ca A N M Bazlur Rahman @bazlur_rahman Java 25: The

    Best Ideas, Integrated 24 Kotlin-like Expressiveness (record) Go-like Concurrency (Virtual Threads) Scala-like Pattern Matching (sealed, switch) Rust-like Native Interop (FFM API) …all delivered within Java’s stable, mature, and unparalleled ecosystem.
  23. https://bazlur.ca A N M Bazlur Rahman @bazlur_rahman But Wait, There’s

    More in Java 25 96 bits (12 bytes) 64 bits (8 bytes) Compact Object Header Ahead-of-Time Class Loading & Linking ZGC: Automatic Heap Scaling Stable Values Quietly, Java is also getting smaller, starting faster, scaling further, and JIT-optimizing harder.
  24. https://bazlur.ca A N M Bazlur Rahman @bazlur_rahman Evolution, Governed By

    Principle Readability & Maintainability Code is read more than it’s written. Backward Compatibility Trillions of lines of code can’t break. World-Class Tooling IDEs, debuggers, and profilers must keep up. 26 Long-term bets, not short-term fixes.
  25. https://bazlur.ca A N M Bazlur Rahman @bazlur_rahman A Deliberate Evolution,

    Not a Reaction 27 PROJECT AMBER Modern Language Features PROJECT LOOM Lightweight Concurrency PROJECT PANAMA Native Interop PROJECT VALHALLA Advanced VM Optimization Each project addresses a distinct dimension (language, runtime, scale, interop) under one stable platform.
  26. https://bazlur.ca A N M Bazlur Rahman @bazlur_rahman The Old Dog

    Learned New Tricks ▌ Expressiveness: Records & Pattern Matching match Kotlin and Scala. ▌ Concurrency: Virtual Threads & Structured Concurrency match Go’s scale with superior safety. ▌ Interop: FFM makes native access practical and safe, ending the pain of JNI and matching Rust. ▌ Performance: Faster startup and execution via JVM-level wins (AOT profiling, compact headers, ZGC). 28 Java didn’t pick a side: it absorbed the best of each.
  27. Thank You Java is boringly powerful. @bazlur.ca linkedin.com/in/bazlur @bazlur_rahman github.com/rokon12

    bazlur.com bazlur.substack.com Modern Concurrency in Java Virtual Threads, Structured Concurrency, and Beyond. O’Reilly, 2025 W H O I A M A N M Bazlur Rahman Java Champion · Sr. Staff Software Engineer M Y B O O K