Java 17 is a new LTS (Long-term support) release of standard Java made available for production use recently. This new release comes with new features and enhancements that include additions to the Java language or APIs, deprecated or removed features and APIs, and so on.
Java 17 supports context-specific deserialization filters, sealed classes, and the preview of pattern matching switch statements.
This article discusses the new features and enhancements in Java 17. There are several new features and enhancements in Java 17; we will discuss the most important of those here.
Read: Oracle Makes Case for Java 17.
Sealed Classes and Interfaces in Java
Sealed classes are not new to Java. It was initially proposed in Java 15 as a preview feature, and now it is available in Java 17 as a full feature. Sealed classes or interfaces can be inherited only by types (i.e., classes and interfaces) that have the necessary permission. In other words, sealed classes and interfaces cannot be extended except by the classes or interfaces allowed.
You can prevent inheritance using the final keyword as well but that would not allow you to specify the types that are permitted to extend the classes and interfaces. Another way is to use a private constructor in a class but that has the same problem, and it would prevent instantiation of the class as well.
The intent of this proposal is that the author of a class or an interface should be able to control in a declarative way, who can implement it thus restricting the use of a super-class.
The bottom line is that, although a superclass should be generally accessible, it should not be available for extension extensively. At the same time, a super-class should not limit its sub-classes by requiring them to be final and preventing them from defining their own state.
You can declare a class as sealed by using the sealed modifier to its declaration. Then after the extends and implements clauses you can specify the permits clause to indicate the classes that are permitted to extend the sealed class. The following code snippet illustrates how you can use a sealed class in Java:
public abstract sealed class Person permits Employee, Manager, Developer { ... }
Pattern Matching for switch Statements in Java
A pattern is made up of a match predicate, which decides if the pattern matches a target, and a set of pattern variables, which are conditionally extracted if the pattern matches the target.
By employing patterns in case labels, pattern matching increases the eloquence and usefulness of switch expressions and statements. Patterns are classified into several types, including type pattern, guarded pattern, parenthesized pattern, and so forth.
A type pattern comprises a type name and the name of a variable to bind the result to as shown in the Java code snippet given below:
if (x instanceof Integer i) { // Write your code here }
The following code example shows how you can use type patterns in switch-case statements in Java:
return switch (obj) { case null -> new String("The value is null..."); case Integer i -> String.format("Integer value is %d", i); case String s -> String.format("String value is %s", s); default -> obj.toString(); }
The guarded pattern is another type of pattern in which the conditional logic is moved to the case labels. It is of the form p&& e where p represents a pattern and e represents an expression, as shown below:
return switch (obj) { case String str && str.length() >= 1 -> String.format("The string value is %s", str); case String s -> String.format("The object contains an empty string"); default -> obj.toString(); };
The parenthesized pattern is yet another type of pattern which can be represented in the form (p), where p is a pattern. The following code samples illustrate how this can be used:
return switch (obj) { case String str && str.length() >= 1 && (str.contains("@")) -> String.format("The string value is %s", str); default -> "The object contains invalid value..."; };
You can now do null checking in switch statements elegantly. Here’s an example that illustrates how this can be achieved:
switch (s) { case null -> System.out.println("The value is null"); default -> System.out.println("The value is not null"); }
Read: A Simple Guide to Using Java Regular Expressions.
Deprecated and Removed in Java 17
The following is a list of items that have been removed or deprecated in the latest release of Java 17.
The Applet API
With Java 17, the Applet API is deprecated ( i.e., it is marked as deprecated for removal in the next release). This was long overdue since all web browsers have either stopped support for Java Applet or will do so soon. The APIs that are marked as deprecated are usually removed in the next release, the release that follows. So, if you’re using an application that leverages the Java Applet API, you should have your migration plans in place.
The Security Manager
Like the Java Applet API, the Security Manager is also deprecated for removal in the next release of Java. Incidentally, the Security Manager has been present since Java 1.0. That was the time when web browsers needed to download Java applets. Now that the Java Applet API is already deprecated, the Security Manager is insignificant. The Security Manager has been used primarily to protect client-side Java Code and very rarely for server-side.
Removal of Remote Method Invocation (RMI)
Remote Method Invocation (RMI), a Java API, allows one object to invoke a method on another object located in a separate address space. Since Java 8, RMI was an optional feature and has been removed from this release.
The Vector API
Java 17 features improved performance and implementation of the vector API, which includes translations between byte vectors and boolean arrays. This API enhances vector computations by expressing them in a way that will compile at runtime to the best vector instructions on supported CPU architectures. Vector operations outperform similar scalar calculations in terms of performance and are widely used in domains such as machine learning, artificial intelligence, and cryptography.
The Foreign Function & Memory API
The foreign function and memory API allow Java applications to communicate with external code and data. The API enables Java programs to contact native libraries and handle native data while avoiding the Java Native Interface (JNI). This is accomplished by effectively executing foreign functions, (i.e., code that runs outside of the Java Virtual Machine (JVM)) and securely accessing foreign memory (for example, memory that is not maintained by the JVM).
Context-Specific Deserialization Filters
Untrusted data can be dangerous because it impacts objects, fields, and relationships. Deserializing untrusted data can be highly harmful since the composition of the incoming data stream influences the objects created, the values stored in their fields, and the relationships between them.
Using a JVM-wide filter factory, developers can set context-specific and dynamically selectable deserialization filters. This allows you to use deserialization filters without updating every stream’s code or making the filter too restrictive/permissive.
This feature is an enhancement of deserialization filters introduced in Java 9. It adds a layer of security when deserializing data by validating the data before deserializing it.
Java 17 Features and Enhancements Summary
James Gosling (Sun Microsystems) created the Java programming language in the mid-1990s. Oracle acquired Sun Microsystems later. Java is very popular all around the world due to the wide variety of features it offers. Java’s promise of “Write once and run anywhere” has been a significant factor in Java’s popularity over the last few decades. Since then, the Java Programming Language has come a long way.
Oracle announced that LTS releases will now be available after every two years. This contrasts with the prior releases, which were separated by a three-year period between each release. Incidentally, Oracle provides support for six months for the non-LTS releases.
The changes in Java 17 are significant compared to its earlier counterparts such as Java 15 or 16. This article presented a discussion on the salient new features and enhancements in Java 17. You can refer to the documentation here for additional details on these features and enhancements.