The past few years I haven't written much Java code and when I did, it was Java 8. Many projects, it seems, have stuck with Java 8 which was released back in 2014. Per the roadmap, Java 8 is designated as LTS, but so are Java 11 and Java 17. In fact, Java 19 is available as of last month and many interesting features have been introduced in the past 8 years. This post is an overview of what's changed. The highlights, in my opinion, so we're up-to-date. I think it's enough to be interesting but not so much that it can't be picked up quickly if you have experience with older Java versions.
First, some name conventions. Java EE is now Jakarta EE. Definitely don't call it J2EE anymore. And since Java 11 Oracle JDK and OpenJDK are basically the same.
Tooling Updates
I won't go into too much detail here. If we are interested in using any of these they are explained and documented well elsewhere. For awareness:
- Java got a REPL called JShell for learning and prototyping interactively (9)
- Java Module System as a new package abstraction (9) - my impression is that this more for the JDK itself and some libraries while OSGi continues to be applicable for regular, modular apps
- Single-file programs can be executed directly and don't need the intermediate javac step (11)
- Multiple new garbage collection options for improved and more consistent performance (11)
- ZGC for low latency
- Epsilon GC no-op
- Linux container awareness for GC, thread pool sizes, etc. (11)
- Application class data sharing (CDS) for improved startup times and lower memory footprints (12) - this also seems to have implications for apps running in containers
API Updates
We want to start incorporating these into our code where applicable, so I created examples to help get used to some of these updates.
Private interface methods (9). Helps to encapsulate code in default methods and create more reusable code.
Variables can have implicit types, including in lambdas, to reduce the verbosity of code (10 and 11).
Switch expressions to simplify code and prepare for pattern matching in the future (12).
Text blocks as way to simplify code with multi-line strings (13).
Simple pattern matching (14). I was introduced to pattern matching when programming in Scala and this seems to continue a trend of Scala features making their way, in some form, to Java. It looks like more is coming in terms of pattern matching options.
Record keyword for immutable data classes (14). Getters, a public constructor, plus equals, hashCode, and toString methods are generated automatically. Lombok is still more flexible, but this is nice for simple cases.
Sealed classes for fine-grained inheritance control (15). Super-classes that are widely accessible but not widely extensible.
Paradigm Updates
For lack of a better name I'll call these paradigm updates as they relate more to programming models.
Virtual threads and structured concurrency (19). The one-to-one kernel to user thread mapping is broken enabling easier asynchronous programming. Read/watch Project Loom: Revolution in Java Concurrency or Obscure Implementation Detail? The tl;dr is we'll still need a higher level of abstraction like reactive programming unless you want to relearn all the low-level concurrency structures.