Java is a versatile and powerful programming language that enables developers to create robust, high-performance applications that can run on any platform. Java is the foundation for virtually every type of networked application and is the global standard for developing and delivering mobile applications, games, web-based content, and enterprise software.
With its rich set of libraries, Java enables developers to create innovative and efficient solutions. The Java platform provides an environment for developing applications with dynamic behavior. The platform also includes a set of tools that enable developers to easily design, test, optimize, and deploy their applications.
It was originally released in 1995 and has since undergone several updates. The Java programming language is a high-level, object-oriented language that is known for its portability and platform independence.
With more than 20 years under its belt, the Java programming language has become one of the most popular languages in use today. In fact, according to the TIOBE Index for October 2022, Java was ranked as the third most popular programming language in the world, behind only C and Python — a trend that has been maintained since 2018.
New in Java 19: An Introduction
The latest update to the Java Development Kit (JDK) was released on September 20, 2022. It’s a non-LTS release that aims to add several new features, including structured concurrency, record patterns, a preview of a foreign function and memory API, and support for the open-source Linux/RISC-V instruction set architecture (ISA).
What does non-LTS mean, you ask? Long-term support (LTS) is an extended support phase for a particular software release. Long-term support includes security updates, bug fixes, and performance enhancements for the duration of the support period. While it’s often not the most up-to-date version of the software, users who require long-term support for their applications may want to consider using the LTS version.
For Oracle, Java’s LTS release is the industry standard until its life cycle ends. As of 2022, the current LTS release is Java 17, and it’s scheduled to end its run in 2026.
In this context, non-LTS releases are small updates that are typically used to test new functionalities and gather feedback from the community. For example, in the case of Java 19, all features mentioned above except for the Linux/RISC-V capability are in either preview or incubator phases.
The Difference Between Experimental, Preview, and Incubator Features
To understand how Java releases work, we have to familiarize ourselves with the notation that Oracle uses: experimental, preview, and incubator. These are all tags used to refer to new features that haven’t been fully integrated into Java.
Java Previews
Previews were introduced back in JEP12. To quote from OpenJDK: “A preview feature is a new feature of the Java language, Java Virtual Machine, or Java SE API that is fully specified, fully implemented, and yet impermanent. It is available in a JDK feature release to provoke developer feedback based on real world use.”
It would be fair to compare a preview with a late-stage beta test. The feature has been thoroughly tested and should be stable. Features that enter into a preview stage are often targets of user feedback that Oracle uses to make fixes or changes as the case demands or to eventually release it.
Preview features have a very short “grace period,” so you can expect very little change and its full adoption is usually within a year of its initial release.
Because preview features aren’t permanent features in the Java SE Platform, they are unavailable by default at compile time and run time. Developers who wish to use preview language features and APIs must explicitly enable them in the compiler and runtime.
Java Experimental
Experimental features are early versions of (mostly) Virtual Machine-level features. While tested, they can be risky, incomplete, or even unstable. To access experimental features, usually, the developer has to enable them using dedicated flags.
To put it in context, if preview features are 95% complete, then experimental features are around 25% complete. They are introduced so that early adopters and enthusiasts can play around with the new feature and provide feedback, report bugs, or start exploring its potential.
Keep in mind that each vendor is free to enable/disable experimental features in their distributions as they see fit.
Java Incubator
Incubating features are APIs distributed in a form of modules with names prefixed with “JDK.incubator.” Just like experimental features, expect incubator APIs to be buggy and unstable. The name incubator comes from the fact that you see these APIs mature throughout several Java releases until they are ready for the preview stage.
Java Projects
Most of the features we are going to talk about today are the result of Java Projects. A Project is a collaborative effort to produce a specific artifact, which may be a body of code, documentation, or some other material.
Any Contributor may propose the creation of a new Project. If supported by at least one Group Lead, whose Group will Sponsor the Project, and approved by a Lazy Consensus of the OpenJDK Members, then the Project will be created.
Famous projects include:
Project Loom
Project Loom is a project that promises to deliver lightweight threads. This is done by having the Java Virtual Machine (JVM) manage scheduling instead of the operating system (OS). This way, the JVM can control the scheduling of all threads and, in theory, provide better performance.
Project Valhalla
Project Valhalla is a project to improve performance in Java. It does this by introducing value types, which are a new form of data type that is programmed like objects but accessed like primitives. This means that they can be stored in a single array, with only a single header field for the entire array and direct access to the individual fields.
Project Panama
Project Panama is a project that makes it easier to connect Java programs to non-Java components, like C-based libraries. The project has several subprojects, which are being released in incubator status in recent releases of Java. These sub-projects include the Foreign-Memory Access API, the Foreign Linker API, the Vector API, and the Foreign-Function Interface API.
Project Amber
Project Amber is a project that is responsible for adding several new features to the Java programming language. Their mission statement is: “explore and incubate smaller, productivity-oriented Java language features that have been accepted as candidate JEPs.”
These features include the var keyword for local variables, text blocks, records, and pattern matching in instances of comparisons. The project is still ongoing and is currently working on adding sealed classes, pattern matching in switches, and pattern matching for records and arrays.
Java 19 New Features
Structured Concurrency
In computer science, concurrency is the ability of different parts or units of a program, algorithm, resource, or device to perform actions independently. Concurrency can improve the performance of a program or system by allowing multiple tasks to be processed simultaneously. It can also help to make better use of resources, such as processors, memory, and disk space.
This concurrency will take multiple tasks running in different threads and handle them as a single unit of work. The goals, according to OpenJDK are as follows:
- Improve the maintainability, reliability, and observability of multithreaded code.
- Promote a style of concurrent programming that can eliminate risks arising from cancellation and shutdown.
This is part of Project Loom, a lightweight concurrency model that allows developers to write concurrent programs more easily. It adds support for virtual threads, which are threads that are not bound to a particular CPU core. This makes it possible for a single thread to use multiple cores at the same time, which can improve performance.
Preview of Record Patterns
This is a preview feature that lets record patterns and type patterns be nested to enable a powerful, declarative, and composable form of data navigation and processing. Built on the pattern matching, for instance, delivered in JDK 16 in March 2021. Plans may call for record patterns to be extended with capabilities such as array patterns and vararg patterns. According to the JDK, the goals are to extend pattern matching to express more complex data queries without changing the syntax of type patterns.
Preview of Foreign Function and Memory API
The foreign function and memory API is a way for Java programs to interact with code and data outside the Java runtime. This API is efficient for invoking foreign functions and accessing foreign memory. It is safe to use and helps avoid the dangers and fragility of the Java Native Interface (JNI). The foreign function and memory API was incubated in JDK 17 and reincubated in JDK 18. The goals of this proposal include being easy to use, having good performance, being general, and being safe.
Preview of Virtual Threads
Virtual threads are lightweight threads that can help reduce the amount of work needed to write, maintain, and observe high-throughput concurrent applications. The goals of virtual threads include:
- Making it easier for server applications written in the simple thread-per-request style to scale with near-optimal hardware utilization
- Making it easier for existing code that uses the java.lang Thread API to adopt virtual threads with minimal change
- Enabling troubleshooting, debugging, and profiling of virtual threads with existing JDK tools
Preview of Pattern Matching for Switch Expressions and Statements
The third preview of pattern matching for switch expressions and statements adds refinements including the replacement of guarded patterns with when clauses in switch blocks. Also, the runtime semantics of a pattern switch when the value of the selector expression is null are more closely aligned with legacy switch semantics.
The plan’s goals include expanding the expressiveness and applicability of switch expressions and statements by allowing patterns to appear in case labels. Other goals include allowing developers to relax the historic null-hostility of a switch when desired, increasing the safety of switch statements, and ensuring that existing switch expressions and statements continue to compile with no changes and execute with identical semantics.
The hope is to eventually support pattern matching throughout Java, adding it to places where expressions are used. This feature is also part of Project Amber.
Fourth Incubation of a Vector API
The vector API is a way for developers to write complex vector algorithms in Java. The API was previously incubated in JDK 16, JDK 17, and JDK 18. Improvements to the API proposed for JDK 19 include enhancements to load and store vectors to and from MemorySegments, as defined by the Foreign Function and Memory API preview. JDK 19 would also add two cross-lane vector operations, compress and expand, together with a complementary vector mask compress operation.
The compress vector operation maps lanes of a source vector, selected by a mask, to a destination vector in lane order, while the expand operation does the inverse. The compress operation is useful in filtering query results. In another addition to the vector API, bitwise integral lanewise operations would be expanded, including operations such as counting the number of one bits, reversing the order of bits, and compressing and expanding bits.
The goals of the API included being clear and concise, platform-agnostic, having reliable runtime and compilation performance on x64 and AArch64 architectures, and enabling “graceful” degradation, for situations in which a vector computation cannot be fully expressed at runtime as a sequence of vector operations. The vector API is from Project Panama.
Linux/RISC-V Port
The Linux/RISC-V port would add support for a hardware instruction set that is already used by many different language toolchains. RISC-V is a family of related instruction set architectures (ISAs), and the port would only support the RV64GV configuration of RISC-V. This is a general-purpose 64-bit ISA that includes vector instructions. The developers of Java may consider adding support for other RISC-V configurations in the future.
Preparing for an Upgrade
Do you want to take Java 19 for a spin? Well, if you want to upgrade keep, these tips in mind:
- Know what you need: Before you upgrade, it’s important to know what your business needs. Make a list of the must-have features and functions that will help your business run more efficiently. If nothing in our feature list jumps out at you as a must-have, you might want to ask yourself if it’s really necessary.
- Do your research: Once you know what you need, it’s time to do some research and find out if Java 19 can help you. Read online reviews, talk to other businesses in your industry, and get recommendations from trusted sources. Remember, some of these features are still experimental, so pay close attention to possible bugs and issues.
- Get organized: Upgrading your software can be a big project, so it’s important to get organized before starting anything. Create a timeline of when you want things done, and make sure everyone involved knows their roles and responsibilities.
- Budget accordingly: One of the most important aspects of upgrading your software is budgeting correctly. Obviously, with short-term release odds, there is very little to consider in terms of budget. But your developers still have to read and learn the documentation so they can make the best of the upgrade. Be ready for that incubation period.
- Start small and test: Make a fresh install in a sandbox and play around for a little bit. Use this as an opportunity so that your team can get acquainted with the new features. Remember that Oracle will provide support for only six months, so we should be seeing Java 20 around March 2023
Is It Time to Upgrade to Java 19 Yet?
If you enjoyed this, be sure to check out one of our other Java articles: