switch
.Download a PDF of this article
Want a simple web server? Java 18 has one. How about a JDK Enhancement Proposal (JEP) that reduces the development and maintenance costs of reflection? Internet address resolution? Java 18 has them. Would you like to see code snippets in Java API documentation? That’s there, starting with Java 18. How about progress on the Vector API, the Foreign Function and Memory API, and pattern matching for switch
? Yes, Java 18 evolves all three of those preview and incubator features.
While many details of Java 18 have been available for months on the JDK 18 page on the OpenJDK site, the platform became generally available on March 22. Developers have been working with the source code and running the binaries, and many contributed comments, bug reports, and suggestions.
For the details on Java 18 and each of the nine JEPs, see the following resources:
As you can see from the API differences link above, there were 186 modified documents between Java 17 (build 35) and Java 18 (build 37), as well as 340 changed contexts. Not all of these are feature enhancements; 2,063 reported issues were marked as fixed for this release.
Note that unlike Java 17, Java 18 is not a Long-Term Support (LTS) release. The next LTS release will be Java 21, set to come out in September 2023. (The length of time between LTS releases was recently shortened to two years.)
The nine JEPs collected into Java 18 can be grouped into four categories: Core library improvements and updates; tooling improvements; previews and incubators; and deprecations, that is, features being prepared for removal in future versions of Java. Here’s a high-level overview of those JEPs.
JEP 400: UTF-8 by default. Standard Java APIs for reading and writing files and for processing text allow a charset to be passed as an argument. A charset governs the conversion between raw bytes and the 16-bit char values of the Java programming language. Java supports several charsets, including US-ASCII, UTF-8, and ISO-8859-1.
This JEP specifies UTF-8, probably the most popular Unicode character set, as the default charset for the standard Java APIs. With this change, APIs that use the default charset will behave consistently across all implementations, operating systems, locales, and configurations.
The goals of this JEP are to make Java programs more predictable and portable when their code relies on the default charset; clarify where the standard Java API uses the default charset; and standardize on UTF-8 throughout the standard Java APIs, except for console I/O.
JEP 408: Simple web server. Developers often need to serve up a static document, such as an HTML file, on a network. For example, computer science curricula often introduce students to web development, which means serving files. This capability can also be needed in everyday software development.
This JEP provides a command-line tool to start a minimal web server that serves static files only—no CGI or servlet-like functionality is available. It’s expected that this tool will be useful for prototyping, ad hoc coding, and testing purposes, particularly in educational contexts.
The goals of this JEP are to offer an out-of-the-box static HTTP file server with easy setup and minimal functionality, thereby making the JDK more approachable. This JEP also provides a default implementation via the command line and a small API for programmatic creation and customization.
JEP 416: Reimplement core reflection with method handles. There are two internal mechanisms for invoking methods and constructors via core reflection. For fast startup, the HotSpot JVM uses native methods for the first few invocations of a specific reflective method or constructor object. After several invocations, it generates bytecode for reflective operations and uses those in subsequent invocations for better peak performance.
This JEP reimplements java.lang.reflect.Method
, Constructor
, and Field
on top of java.lang.invoke
method handles, which makes method handles the underlying mechanism for reflection. The intended result is that the future maintenance and development costs of both the java.lang.reflect
and java.lang.invoke
APIs will be reduced.
JEP 418: Internet address resolution SPI (service-provider interface). The java.net.InetAddress
API resolves host names to Internet Protocol (IP) addresses, and vice versa. Before JEP 418, the API used the operating system’s native resolver, which was typically configured to use a combination of a local hosts file and the Domain Name System (DNS). This wasn’t great because calls can be blocking, and it’s not easy to handle virtual threads.
Therefore, this JEP defines an SPI for host name and address resolution, so java.net.InetAddress
can use resolvers other than the platform’s built-in resolver.
JEP 413: Code snippets in Java API documentation. Authors of API documentation frequently include fragments of source code in documentation comments. However, there’s no way for tools to reliably detect code fragments and check their validity. Further, such fragments might contain HTML and may not be editable in an IDE.
This JEP defines a new @snippet
tag for Javadoc’s standard doclet, which simplifies the inclusion of example source code in API documentation. The tag facilitates the validation of source code fragments by providing API access to those fragments. The new tag also enables modern styling, such as syntax highlighting, and allows for better IDE support for creating and editing snippets.
JEP 417: Vector API (third incubator). A vector computation consists of a sequence of operations on vectors. A binary operation applied to two vectors with the same number of lanes would, for each lane, apply the equivalent scalar operation on the corresponding two scalar values from each vector. This is commonly referred to as single instruction, multiple data (SIMD).
The HotSpot JVM already supports autovectorization, which transforms scalar operations into superword operations, which are then mapped to vector instructions. However, the set of transformable scalar operations is limited and can also be fragile with respect to changes in code shape. Furthermore, only a subset of the available vector instructions might be utilized, limiting the performance of generated code.
This JEP, which is in its third incubator, creates an API to express vector computations that reliably compile at runtime to optimal vector instructions on supported CPU architectures, thus achieving performance superior to equivalent scalar computations. The previous incubators were offered in Java 16 and Java 17.
The bottom line is that the Vector API will now offer a platform-agnostic, reliable way of clearly and concisely expressing a wide range of vector computations for supported CPU architectures.
JEP 419: Foreign Function and Memory API (second incubator). Although Java APIs expose non-Java resources to developers, it can be a challenge to access non-Java code and data on the same machine as the JVM—but which are outside the Java runtime.
This JEP, which is in its second incubator, introduces an API by which Java programs can interoperate with code and data outside of the Java runtime. By efficiently invoking foreign functions (defined as code outside the JVM) and by safely accessing foreign memory (that is, memory not managed by the JVM), the API lets Java programs call native libraries and process native data without the brittleness and danger of the Java Native Interface (JNI).
This JEP focuses on ease of use, performance, and safety. It is also designed to operate on different kinds of foreign memory (such as native memory, persistent memory, and managed heap memory) and, over time, it evolved to accommodate other platforms (such as 32-bit x86) and foreign functions written in languages other than C (such as C++ and Fortran).
The previous incubator was in Java 17, and it combined two previous incubating APIs: the Foreign-Memory Access API and the Foreign Linker API.
JEP 420: Pattern matching for switch (second preview). In Java 16, JEP 394 (pattern matching for instanceof
) extended the instanceof
operator to take a type pattern and perform pattern matching. JEP 420 enhances the Java language with pattern matching for switch
expressions and statements, along with extensions to the language of patterns.
Extending pattern matching to switch
allows an expression to be tested against many different patterns, each with a specific action, so complex data-oriented queries can be expressed concisely and safely.
The first preview of pattern matching for switch
was in Java 17; this version adds several refinements.
JEP 421: Deprecate finalization for removal. The problem addressed by this JEP is the need for efficient prevention of resource leaks. If the JVM’s garbage collector reclaims an unused resource’s memory before the resource itself can be released back to the operating system, the information needed to release that resource is lost. In those cases, because the operating system considers the resource to still be in use, it can’t be released. Thus, there is a leak.
The finalization mechanism, introduced in Java 1.0, was designed to avoid resource leaks, but this mechanism is flawed because it introduces unpredictable latency, unconstrained behavior, and unspecified threading. It is also always enabled, whether it’s needed or not.
Fortunately, there are newer, more effective mechanisms, such as try-with-resources and cleaners.
This JEP deprecates finalization for removal in a future release. Finalization remains enabled by default for now but can be disabled to facilitate early testing. In a future release, finalization will be disabled by default, and in a later release it will be removed.
Java 18 offers nine JEPs in four buckets. Probably most developers will focus on pattern matching for switch
—but there’s something in Java 18 for everyone.
Alan Zeichick is editor in chief of Java Magazine and editor at large of Oracle’s Content Central group. A former mainframe software developer and technology analyst, Alan has previously been the editor of AI Expert, Network Magazine, Software Development Times, Eclipse Review, and Software Test & Performance. Follow him on Twitter @zeichick.