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

Java 30 + Java 25 @ OpenSouthCode 2025

Java 30 + Java 25 @ OpenSouthCode 2025

Slides de mi charla en OpenSouthCode 2025 especial sobre el 30 aniversario de Java y la publicación de Java 25, realizada el 20 de junio de 2025.

Slides from my talk at OpenSouthCode 2025 about the 30th anniversary of Java and the release of Java 25.

Slides in English.

Avatar for Jorge Hidalgo

Jorge Hidalgo

June 20, 2025
Tweet

More Decks by Jorge Hidalgo

Other Decks in Technology

Transcript

  1. Copyright © 2025 Jorge Hidalgo – CC BY 4.0 Copyright

    © 2025 Jorge Hidalgo – CC BY 4.0 Java 30 + Java 25 30th anniversary of Java and what’s new in Java 25 OpenSouthCode 20/6/2025
  2. Copyright © 2025 Jorge Hidalgo – CC BY 4.0 Director

    Asociado – Ingeniería del Software – Accenture Responsable de DevOps e Ingeniería de Plataformas para Iberia Responsable de Arquitectura Empresarial y de Sistemas para el Centro de Tecnología Avanzada Responsable de la Comunidad de Práctica Java Global Java Champion Muy activo en las comunidades: Coorganizador en MálagaJUG / BoquerónSec Coorganizador en OpenSouthCode / OpenSouthKids Codemotion Ambassador @deors.bsky.social in/deors Jorge Hidalgo Copyright © 2025 Jorge Hidalgo – CC BY 4.0
  3. Copyright © 2025 Jorge Hidalgo – CC BY 4.0 Agenda

    1. Brief history of Java 2. Java through the times 3. Fast refresh from Java 9 to 24 4. What’s new in Java 25
  4. Copyright © 2025 Jorge Hidalgo – CC BY 4.0 The

    Star7 Demo Project, 1991 5 https://www.youtube.com/watch?v=1CsTH9S79qI || https://archive.org/details/Star7Demo
  5. Copyright © 2025 Jorge Hidalgo – CC BY 4.0 Java

    Timeline 6 Java official ‘birthday’ Java SE 1.2.2 + Java EE 1.2 ”kings” of enterprise software ‘Legacy’ Java maturity Generics Annotations Auto(un)boxing Lambdas Probably, the most used release of all time LTS at least up to 2026 (Eclipse Temurin) (2030 with Oracle extended support) Modules JShell Continuous innovation Early community involvement and feedback (incubators, previews) https://javaalmanac.io/jdk/ || https://versionlog.com/java/
  6. Copyright © 2025 Jorge Hidalgo – CC BY 4.0 Notes

    for the unwary Java developer 6 MONTH release cycle (March & September) LTS release every 2 YEARS Latest release is Java 24 Previous LTS is Java 17 Current LTS is Java 21 NEXT LTS will be JAVA 25 7
  7. Copyright © 2025 Jorge Hidalgo – CC BY 4.0 Notes

    for the unwary Java developer Java is FREE and open source Code is hosted and developed at GitHub: https://github.com/openjdk/jdk MANY DISTRIBUTIONS of the JDK packages and others 8
  8. Copyright © 2025 Jorge Hidalgo – CC BY 4.0 Notes

    for the unwary Java developer Java runs just-in-time (JIT) Java runs ahead-of-time (AOT) Java runs from bytecodes and from native images Project Leyden 9
  9. Copyright © 2025 Jorge Hidalgo – CC BY 4.0 Fast

    refresh – Java 9 to Java 12 10 Java 9 Modules Interface private methods JShell Java 10 Local variable type inference (var) Container awareness Java 11 String enhancements Local-variable for Lambdas Flight Recorder is open source Java 12 Enhanced switch
  10. Copyright © 2025 Jorge Hidalgo – CC BY 4.0 Fast

    refresh – Java 13 to Java 16 11 Java 13 String text blocks (preview) switch expressions (preview) Java 14 switch expressions (final) Records (preview) Pattern matching for instanceof (preview) Enhanced NullPointerException Java 15 String text blocks (final) Sealed classes (preview) Records (2nd preview) Pattern matching for instanceof (2nd preview) Hidden classes Z Garbage Collector Shenandoah GC Java 16 Records (final) Pattern matching for instanceof (final) Vector API (incubator) Sealed classes (2nd preview) Static members in inner classes Stream.toList() Migration from Mercurial to Git Windows ARM64 & Alpine Ports
  11. Copyright © 2025 Jorge Hidalgo – CC BY 4.0 Enhanced

    switch & switch expressions before int days = 0; switch (month) { case 1: case 3: case 5: case 7: case 8: case 10: case 12: days = 31; break; case 4: case 6: case 9: days = 30; break; case 2: days = 28; break; default: throw new IllegalArgumentException("Invalid month"); } 12
  12. Copyright © 2025 Jorge Hidalgo – CC BY 4.0 Enhanced

    switch & switch expressions 13 after int days = switch (month) { case 1, 3, 5, 7, 8, 10, 12 -> 31; case 4, 6, 9 -> 30; case 2 -> 28; default -> 0; }; or int days = switch (month) { case 1, 3, 5, 7, 8, 10, 12 -> 31; case 4, 6, 9 -> 30; case 2 -> { System.out.println("check the year!"); yield 28; } default -> 0; };
  13. Copyright © 2025 Jorge Hidalgo – CC BY 4.0 String

    text blocks before var dbQuery = """ CREATE TABLE 'TEST'.'EMPLOYEE' ( 'ID' INT NOT NULL DEFAULT 0, 'FIRST_NAME' VARCHAR(100) NOT NULL, 'LAST_NAME' VARCHAR(100) NULL, 'STAT_CD' TINYINT NOT NULL DEFAULT 0 ); """; System.out.println(dbQuery); 14
  14. Copyright © 2025 Jorge Hidalgo – CC BY 4.0 Records

    15 before class AuditInfo { private LocalDateTime createdOn; private String createdBy; private LocalDateTime updatedOn; private String updatedBy; public AuditInfo(LocalDateTime createdOn, String createdBy, LocalDateTime updatedOn, String updatedBy) { this.createdOn = createdOn; this.createdBy = createdBy; this.updatedOn = updatedOn; this.updatedBy = updatedBy; } public LocalDateTime getCreatedOn() { return createdOn; } // rest of getters, setters, equals, hashCode }
  15. Copyright © 2025 Jorge Hidalgo – CC BY 4.0 Records

    16 after record AuditInfo( LocalDateTime createdOn, String createdBy, LocalDateTime updatedOn, String updatedBy) { } how to use a Record var myAudit = new AuditInfo( LocalDateTime.now().minusHours(1), "jorge", LocalDateTime.now(), "julio"); System.out.println(myAudit.updatedBy());
  16. Copyright © 2025 Jorge Hidalgo – CC BY 4.0 Pattern

    matching for instanceof 17 before interface Shape { static double getPerimeter(Shape shape) throws IllegalArgumentException { if (shape instanceof Rectangle) { Rectangle r = (Rectangle) shape; return 2 * r.length() + 2 * r.width(); } else if (shape instanceof Circle) { Circle c = (Circle) shape; return 2 * c.radius() * Math.PI; } else { throw new IllegalArgumentException( "Unrecognized shape"); } } } class Rectangle implements Shape {...} class Circle implements Shape {...}
  17. Copyright © 2025 Jorge Hidalgo – CC BY 4.0 Pattern

    matching for instanceof 18 after interface Shape { static double getPerimeter(Shape shape) throws IllegalArgumentException { if (shape instanceof Rectangle r) { return 2 * r.length() + 2 * r.width(); } else if (shape instanceof Circle c) { return 2 * c.radius() * Math.PI; } else { throw new IllegalArgumentException( "Unrecognized shape"); } } }
  18. Copyright © 2025 Jorge Hidalgo – CC BY 4.0 Pattern

    matching for instanceof 19 even better interface Shape { static double getPerimeter(Shape shape) throws IllegalArgumentException { ... } else if (shape instanceof Circle c && c.radius() == 0) { throw new IllegalArgumentException( "A circle with 0 radius is a point"); ... } } }
  19. Copyright © 2025 Jorge Hidalgo – CC BY 4.0 Fast

    refresh – Java 17 and Java 18 20 Java 17 Sealed classes (final) Vector API (2nd incubator) Pattern matching for switch (preview) Foreign function and memory API (incubator) Apple AArch64 (macOS) port Removal of Applet API Java 18 Vector API (3rd incubator) Pattern matching for switch (2nd preview) Foreign function and memory API (2nd incubator) Simple Web Server UTF-8 as default charset Code snippets in Javadocs Deprecation of finalization Java 17 is, probably, where most of you are working nowadays
  20. Copyright © 2025 Jorge Hidalgo – CC BY 4.0 Fast

    refresh – Java 19 and Java 20 21 Java 19 Virtual threads (preview) Structured concurrency (incubator) Vector API (4th incubator) Pattern matching for switch (3rd preview) Record patterns (preview) Foreign function and memory API (preview) Java 20 Virtual threads (2nd preview) Structured concurrency (2nd incubator) Scoped values (incubator) Vector API (5th incubator) Pattern matching for switch (4th preview) Record patterns (2nd preview) Foreign function and memory API (2nd preview)
  21. Copyright © 2025 Jorge Hidalgo – CC BY 4.0 Fast

    refresh – Java 21 and Java 22 22 Java 21 Virtual threads (final) Pattern matching for switch (final) Record patterns (final) String templates (preview) Compact Source Files and Instance Main Methods (preview) Sequenced collections Foreign function and memory API (3rd preview) Structured concurrency (preview) Scoped values (preview) Vector API (6th incubator) Generational ZGC Java 22 Foreign function and memory API (final) Unnamed variables & patterns String templates (2nd preview) Compact Source Files and Instance Main Methods (2nd preview) Flexible constructors (preview) Stream gatherers (preview) Structured concurrency (2nd preview) Scoped values (2nd preview) Vector API (7th incubator) Launch multi-file programs
  22. Copyright © 2025 Jorge Hidalgo – CC BY 4.0 Virtual

    threads 23 before 1 java.lang.Thread = 1 OS Thread after 1 java.lang.Thread = 1 virtual Thread JVM OS ← these are limited and can be exhausted easily JVM VT OS ← OS threads are more wisely used e.g., shared by multiple virtual threads
  23. Copyright © 2025 Jorge Hidalgo – CC BY 4.0 Virtual

    threads 24 example with OS threads double start = System.currentTimeMillis(); try (var executor = Executors. newFixedThreadPool(1_000)) { IntStream.range(0, 10_000).forEach(i -> { executor.submit(() -> { Thread.sleep(1000); return i; }); }); } double finish = System.currentTimeMillis(); System.out.println(finish - start);
  24. Copyright © 2025 Jorge Hidalgo – CC BY 4.0 Virtual

    threads 25 example with virtual threads double start = System.currentTimeMillis(); try (var executor = Executors. newVirtualThreadPerTaskExecutor()) { IntStream.range(0, 10_000).forEach(i -> { executor.submit(() -> { Thread.sleep(1000); return i; }); }); } double finish = System.currentTimeMillis(); System.out.println(finish - start);
  25. Copyright © 2025 Jorge Hidalgo – CC BY 4.0 Pattern

    matching for switch 26 use types as input for switch blocks supports null supports using records supports conditional logic with keyword when interface Shape {} record Rectangle(double length, double width) implements Shape {} record Circle(double radius) implements Shape {}
  26. Copyright © 2025 Jorge Hidalgo – CC BY 4.0 Pattern

    matching for switch 27 static double getPerimeter(Shape shape) throws IllegalArgumentException { return switch (shape) { case null -> throw new IllegalArgumentException( "Null reference not allowed"); case Rectangle r -> 2 * r.length() + 2 * r.width(); case Circle c -> 2 * c.radius() * Math.PI; default -> throw new IllegalArgumentException( "Unrecognized shape"); }; } var r1 = new Rectangle(2, 5); var c1 = new Circle(8); getPerimeter(r1); getPerimeter(c1); getPerimeter(null);
  27. Copyright © 2025 Jorge Hidalgo – CC BY 4.0 Pattern

    matching for switch 28 static void describeShape(Shape shape) throws IllegalArgumentException { switch (shape) { case null -> throw new IllegalArgumentException( "Null reference not allowed"); case Rectangle r when (r.length() > 100 || r.width() > 100) -> System.out.println("it’s huge! (%.1f, %.1f)". formatted(r.length(), r.width())); case Rectangle r -> System.out.println("normal rectangle"); case Circle c -> System.out.println("a circle"); default -> throw new IllegalArgumentException( "Unrecognized shape"); }; } describeShape(r1); describeShape(c1); var r2 = new Rectangle(150, 110); describeShape(r2);
  28. Copyright © 2025 Jorge Hidalgo – CC BY 4.0 Record

    patterns 29 extends pattern matching for instanceof to records allows for record deconstruction record Point(int x, int y) {} enum Color { RED, GREEN, BLUE } record ColoredPoint(Point p, Color c) {} record ColoredRectangle(ColoredPoint upperLeft, ColoredPoint lowerRight) implements Shape {} static void describeColoredShape(Shape s) { if (s instanceof ColoredRectangle cr) { System.out.println("a colored rectangle"); System.out.println("upper left corner x = " + cr.upperLeft().p().x()); } }
  29. Copyright © 2025 Jorge Hidalgo – CC BY 4.0 Record

    patterns 30 alternate way static void describeColoredShape(Shape s) { if (s instanceof ColoredRectangle( ColoredPoint(Point(var x1, var y1), var c1), ColoredPoint(Point(var x2, var y2), var c2))) { System.out.println("a colored rectangle"); System.out.println("upper left corner x = " + x1); } } var cr = new ColoredRectangle( new ColoredPoint(new Point(2, 5), Color.RED), new ColoredPoint(new Point(15, 12), Color.BLUE)); describeColoredShape(cr);
  30. Copyright © 2025 Jorge Hidalgo – CC BY 4.0 Record

    patterns 31 also works within switch blocks also works in conditionals static void describeShape(Shape shape) throws IllegalArgumentException { switch (shape) { case null -> throw new IllegalArgumentException( "Null reference not allowed"); case Rectangle(var l, var w) when (l > 100 || w > 100) -> System.out.println("it’s huge! (%.1f, %.1f)". formatted(l, w)); case Rectangle r -> System.out.println("normal rectangle"); case Circle c -> System.out.println("a circle"); default -> throw new IllegalArgumentException( "Unrecognized shape"); }; } describeShape(r2);
  31. Copyright © 2025 Jorge Hidalgo – CC BY 4.0 Unnamed

    variables & patterns 32 anywhere a value does not need to be referred makes it clear that a value is intentionally unused static void describeColoredShape(Shape s) { if (s instanceof ColoredRectangle( ColoredPoint(Point(var x1, var _), var _), var _)) { System.out.println("a colored rectangle"); System.out.println("upper left corner x = " + x1); } } describeColoredShape(cr);
  32. Copyright © 2025 Jorge Hidalgo – CC BY 4.0 Unnamed

    variables & patterns 33 another example void someLogic() { try { thisMayFail(); } catch (SomeException _) { System.out.println("something happened"); } }
  33. Copyright © 2025 Jorge Hidalgo – CC BY 4.0 Sequenced

    collections 34 with ‘classic’ Java <21 collections • access to first and last element is not consistent • iterating in natural sequence is consistent (iterators, for each) • iterating in inverted order is not consistent (even hard to achieve) Collection type First element Last element List l.get(0) l.get(l.size() - 1) Deque d.getFirst() d.getLast() SortedSet s.first() s.last() LinkedHashSet hs.iterator().next() no direct way
  34. Copyright © 2025 Jorge Hidalgo – CC BY 4.0 Sequenced

    collections 35 Java 21 introduces brand new sequenced collections SequencedCollection<E> SequencedSet<E> SequencedMap<K, V> with a consistent API addFirst() addLast() getFirst() getLast() removeFirst() removeLast() reversed() existing collections also implement the new interfaces, e.g., List (therefore ArrayList, LinkedList, Stack, Vector) LinkedHashMap, TreeMap, LinkedHashSet, TreeSet https://docs.oracle.com/en/java/javase/21/core/creating-sequenced-collections-sets-and-maps.html
  35. Copyright © 2025 Jorge Hidalgo – CC BY 4.0 Sequenced

    collections 36 https://docs.oracle.com/en/java/javase/21/core/creating-sequenced-collections-sets-and-maps.html
  36. Copyright © 2025 Jorge Hidalgo – CC BY 4.0 Fast

    refresh – Java 23 and Java 24 37 Java 23 Module imports (preview) Primitive types in patterns, instanceof and switch (preview) String templates (removed) Compact Source Files and Instance Main Methods (3rd preview) Flexible constructors (2nd preview) Stream gatherers (2nd preview) Structured concurrency (3rd preview) Scoped values (3rd preview) Vector API (8th incubator) Markdown in Javadocs Generational ZGC by default Java 24 Module imports (2nd preview) Primitive types in patterns, instanceof and switch (2nd preview) Compact Source Files and Instance Main Methods (4th preview) Flexible constructors (3rd preview) Stream gatherers Structured concurrency (4th preview) Scoped values (4th preview) Vector API (9th incubator) AOT class loading and linking https://docs.oracle.com/en/java/javase/24/migrate/significant-changes-jdk-24.html
  37. Copyright © 2025 Jorge Hidalgo – CC BY 4.0 Let’s

    get ready for Java 25 38 Java 25 Module imports (final) Compact Source Files and Instance Main Methods (final) Flexible constructors (final) Primitive types in patterns, instanceof and switch (3rd preview) Structured concurrency (5th preview) Scoped values (final) Vector API (10th incubator) Stable values (preview) Compact object headers (final) AOT CLI ergonomics AOT method profiling Generational Shenandoah https://openjdk.org/projects/jdk/25/
  38. Copyright © 2025 Jorge Hidalgo – CC BY 4.0 Module

    imports 39 reduce verbosity when importing multiple classes import module java.base; import module java.logging; import module java.sql; importing a module applies to all types exported directly or indirectly by that module (transitive dependencies) disambiguation is needed before using a symbol present in multiple modules import module java.base; import module java.desktop; import java.util.List; List l = ... https://openjdk.org/jeps/511
  39. Copyright © 2025 Jorge Hidalgo – CC BY 4.0 Compact

    Source Files and Instance Main Methods 40 the “brand-new minimal Java program” void main() { IO.println("Hello World!"); } how to read this • Implicit new class in the default package named from the source file name • Implicit module import to java.base • Uses the new utility class java.lang.IO https://openjdk.org/jeps/512
  40. Copyright © 2025 Jorge Hidalgo – CC BY 4.0 Compact

    Source Files and Instance Main Methods 41 another example void main() { String name = IO.readln("Please enter your name: "); IO.print("Pleased to meet you, "); IO.println(name); } $ java HelloWorld.java $ javac HelloWorld.java $ java HelloWorld https://openjdk.org/jeps/512
  41. Copyright © 2025 Jorge Hidalgo – CC BY 4.0 Flexible

    constructors 42 allows for certain logic before invoking super() convenient to check inputs and prepare values before the object is instantiated (no more half-ready objects) class A { A() { // A prologue super(); // A epilogue } } class B extends A { B() { // B prologue super(); // B epilogue } } https://openjdk.org/jeps/513 B prologue --> A prologue --> Object constructor body --> A epilogue B epilogue
  42. Copyright © 2025 Jorge Hidalgo – CC BY 4.0 Flexible

    constructors 43 allows for certain logic before invoking super() convenient to check inputs and prepare values before the object is instantiated (no more half-ready objects) class A { A() { IO.print("2"); // A prologue super(); IO.print("3"); // A epilogue } } class B extends A { B() { IO.print("1"); // B prologue super(); IO.print("4"); // B epilogue } } var b = new B() // prints: 1234 https://openjdk.org/jeps/513