Core JavaJava Basics

Features & Changes in Java 17

1. Introduction

This article is design for the eager persons that want to keep up to date with the Features & Changes in Java 17.

The cadence of Java versions is release every 6 months. The release date of this version was 14th September 2021, as the official site related. The current LTS version is JDK 17. Previous LTS version was JDK 11. The LTS License is available until September 2026 with the possibility of extended support as Oracle related.

If you want to use JDK from Oracle you can use it for free in the Live production environment considering the Terms and Conditions defined by Oracle. For an Open Source solution, you can choose OpenJDK under GPL (General Public License) License from Oracle.

The JDK 17 LST has support for the new Apple computers.

2. Download and Install

To download the JDK 17 from Oracle’s official website access this link: https://www.oracle.com/java/technologies/downloads/. There you can find more information about different platforms where you can use it (Linux, macOS, and Windows).

Download Open JDK from the official website: https://jdk.java.net/17/. Available for the platforms: Linux, macOS, and Windows.

NOTE:

Please make sure that you set the environment variables JAVA_HOME with the new path. In the environment variable PATH append this value: $JAVA_HOME/bin.

3. Comparison between Oracle JDK and OpenJDK

As the official website mentioned, the big difference between Oracle JDK and OpenJDK is only from the license point of view.

3.1 What is Open JDK?

OpenJDK is the place to collaborate on an open-source implementation on Java Platform SE(https://openjdk.java.net/). OpenJDK works under the GNU General Public License (GPL).

4. Important 17 changes in Java 17

Below we describe a complete API modules specification in JDK 17:

  • Java.base Defines the foundational APIs of the Java SE Platform.
  • Java.compiler Defines the Language Model, Annotation Processing, and Java Compiler APIs.
  • Java.datatransfer Defines the API for transferring data between and within applications.
  • Java.desktop Defines the AWT and Swing user interface toolkits, plus APIs for accessibility, audio, imaging, printing, and JavaBeans.
  • Java.instrument Defines services that allow agents to instrument programs running on the JVM.
  • Java.logging Defines the Java Logging API.
  • Java.management Defines the Java Management Extensions (JMX) API.
  • Java.management.rmi Defines the RMI connector for the Java Management Extensions (JMX) Remote API.
  • Java.naming Defines the Java Naming and Directory Interface (JNDI) API.
  • Java.net.http Defines the HTTP Client and WebSocket APIs.
  • Java.prefs Defines the Preferences API.
  • Java.rmi Defines the Remote Method Invocation (RMI) API.
  • Java.scripting Defines the Scripting API.
  • Java.se Defines the API of the Java SE Platform.
  • Java.security.jgss Defines the Java binding of the IETF Generic Security Services API (GSS-API).
  • Java.security.sasl Defines Java support for the IETF Simple Authentication and Security Layer (SASL).
  • Java.sql Defines the JDBC API.
  • Java.sql.rowset Defines the JDBC RowSet API.
  • Java.transaction.xa Defines an API for supporting distributed transactions in JDBC.
  • Java.xml Defines the Java API for XML Processing (JAXP), the Streaming API for XML (StAX), the Simple API for XML (SAX), and the W3C Document Object Model (DOM) API.
  • Java.xml.crypto Defines the API for XML cryptography.

In the next section, we will continue with the features in JDK 17 and some API changes.

4.1 JEP 409: Sealed Classes(specification)

In this paragraph we will discuss the first new important feature is Sealed Classes. This new feature is present also in Java 15 as a preview feature and now in JDK, the Sealed Classes is complete. The Sealed Classes and Interfaces restrict other classes or interfaces that may extend or implement them. The purpose of this feature is to allow the author of the class or interface to control which class or interface can implement. This improvement provides a more declarative way than the old access modifiers available in Java, which are: public, protected, default, and private to better use of a superclass.

Support future directions in pattern matching by providing a foundation for the exhaustive analysis of patterns.

class SealedClassExample {

    public static void main(String[] args) {
        final AutoVehicle autoVehicle = new AutoVehicle();
        autoVehicle.autoVehicleType();
        final AutoVehicle autoVehicleCar = new Car();
        autoVehicleCar.autoVehicleType();
        final AutoVehicle autoVehicleBus = new Bus();
        autoVehicleBus.autoVehicleType();
        final AutoVehicle autoVehicleTruck = new Truck();
        autoVehicleTruck.autoVehicleType();
    }
}

sealed class AutoVehicle permits Car, Bus, Truck {

    public void autoVehicleType() {
        System.out.println("AutoVehicle base class...");
    }
}

final class Car extends AutoVehicle {

    @Override
    public void autoVehicleType() {
        System.out.println("Car AutoVehicle class...");
    }
}

final class Bus extends AutoVehicle {

    @Override
    public void autoVehicleType() {
        System.out.println("Bus AutoVehicle class...");
    }
}

final class Truck extends AutoVehicle {

    @Override
    public void autoVehicleType() {
        System.out.println("Truck AutoVehicle class...");
    }
}

In the context of the sealed, in case a class is not in the permit list you will see this error:

java: class is not allowed to extend sealed class: sealed.AutoVehicle (as it is not listed in its permits clause)

4.2 JEP 406: Pattern Matching for switch (Preview)(specification)

Enhancement for pattern matching in the switch expression and statements along with extensions to the language of patterns. This type of pattern matches against some types with a specific action and this can be concisely and safe. This is the easy way to cast an object to a specific type.

The goals of this feature are:

  • Expand the expressiveness and applicability of switch expressions and statements by allowing patterns to appear in case labels.
  • Introduce two new kinds of patterns: guarded patterns, to allow pattern matching logic to be refined with arbitrary Boolean expressions, and parenthesized patterns, to resolve some parsing ambiguities.
  • Ensure that all existing switch expressions and statements continue to compile with no changes and execute with identical semantics.

The concept of this feature was adopted in the previous version of Java for the instance of operator to perform a pattern matching operation.

As we are familiar with, in the case of a null value in a switch case expression, throw a “NullPointerException”. This check should be done outside of the switch expression. With the latest improvements, you can create a null case to catch null values in the same way as another case label. The list can continue with other new features for pattern matching but we will move to the next features in JDK17.

public class PatternMatching {

    public static void main(String[] args) {
        getObjectType("String value");
        getObjectType(2);

        getObjectTypeSwitchStatement(null);
        getObjectTypeSwitchStatement("test");
        getObjectTypeSwitchStatement(2);
    }

    static void getObjectType(Object o) {
        if (o instanceof String value) {
            System.out.println("The object type is String. Value: " + value);
        } else if (o instanceof Integer value) {
            System.out.println("The object type is Integer. Value: " + value);
        } else {
            System.out.println("No determined Type....");
        }
    }

    static void getObjectTypeSwitchStatement(Object o) {
        switch (o) {
            case null -> System.out.println("Null object case");
            case Integer value -> System.out.println("Integer value. Value: " + value);
            case String value && value.contains("test") -> System.out.println("");
            default -> System.out.println("Default value");
        }

        final Object result = switch (o) {
            case null -> null;
            case String value -> value;
            case Integer value -> value;
            case default -> "Default value";
        };

        System.out.println("Result from switch expression: " + result);
    }

}

4.3 JEP 382: New macOS Rendering Pipeline(client-libs/2d)

Java 2D API used by Swing APIs for rendering, can now use the new Apple Metal. This feature is disabled by default so rendering still uses OpenGL API which is deprecated by Apple but still offers support. To enable this feature, you have to pass to the running command this system property: -Dsun.java2d.metal=true. Using Metal or OpenGL is transparent and it does not affect Java API, the only difference is in the internal implementation.

4.4 New API for Accessing Large Icons(client-libs/javax.swing)

This enhancement allows you to have access to higher-quality icons when possible. This is fully implemented on the Windows platform and for other platforms, it will be enhanced later.

Example of code:

FileSystemView fsv = FileSystemView.getFileSystemView();
Icon icon = fsv.getSystemIcon(new File("application.exe"), 64, 64);
JLabel label = new JLabel(icon);

The user can obtain a higher quality icon for the ‘application.exe’

4.5 DatagramSocket Can Be Use Directly to Join Multicast Groups (core-libs/java.net)

java.net.DatagramSocket has been updated in the JDK 17 to add support for joining multicast groups. The methods joinGroup and leaveGroup is define to do the action for multicast groups. These new changes can be use for multicast applications since it is not need to use legacy code java.net.MulticastSocket API. The class MulticastSocket API works as before even if some of the methods are deprecated.

4.6 Add support for UserDefinedFileAttributeView on macOS(core-libs/java.nio).

A new feature is implement on macOS for file system providers to support extended attributes. The API java.nio.file.attribute.UserDefinedFileAttributeView can now be use to obtain a view of a file’s extended attributes. Previous version not support this feature.

4.7 JEP 356: Enhanced Pseudo-Random Number Generators(core-libs/java.util)

A new interface for pseudorandom number generators(PRNGs), including jumpable PRNGs and an additional class of splittable PRNG algorithms (LXM). It keeps the same behaviour of class java.util.Random and eliminates the code duplication. This class (RandomGenerator) provides methods for ints, longs, doubles, nextBoolean, nextInt, nextLong, nextDouble, nextFloat. With this new release some new interfaces is add that extend RandomGenerator (except one):

  • SplittableRandomGenerator
  • JumpableRandomGenerator
  • LeapableRandomGenerator
  • ArbitrarilyJumpableRandomGenerator extends LeapableRandomGenerator.

To create an instance of these interfaces you can use the factory method for this, which is call RandomGeneratorFactory. This factory uses ServiceLoader to load up the classes.

public class PseudoNumbersGenerator {

    public static void main(String[] args) {
        final RandomGenerator randomGenerator = new Random();
        //return a IntStreams with multiple numbers
        System.out.println(randomGenerator.ints().count());
        System.out.println(randomGenerator.longs().count());
        System.out.println(randomGenerator.doubles().count());
        System.out.println(randomGenerator.nextBoolean());
        System.out.println(randomGenerator.nextInt());
        System.out.println(randomGenerator.nextLong());
        System.out.println(randomGenerator.nextDouble());
        System.out.println(randomGenerator.nextFloat());
    }
}

4.8 Modernization of Ideal Graph Visualizer(hotspot/compiler)

Ideal Graph Visualizer is a useful tool to explore visually and interactively the intermediate representation for the JVM and JTC (Just in Time Compiler). Enhancement includes:

  • Support for running IGV on up to JDK 15 (the latest version supported by IGV’s underlying NetBeans Platform)
  • Faster, Maven-based IGV build system
  • Stabilization of block formation, group removal, and node tracking
  • More intuitive coloring and node categorization in default filters
  • Ranked quick node search with more natural default behavior

Some graphs can be drawn with basic functionality such as graph loading and visualization. The graph generated in the previous JDK release is partially compatible with the current IGV.

You can find additional information about how to run and configure the IGV here.

4.9 Source Details in Error Messages(tools/javadoc(tool))

This is an improvement in the Javadoc tool that in case of an error in the input source file, it will print the line of the error and point to the position of the line similar to the compiler (javac). The logging “info” messages are now write to the standard error stream; on other hand, the stream requested by the command line, like the helper command line, will be output to the standard output stream.

generating java doc JDK 17

Comparison between JDK 11 and JDK 17 in the generating javadoc. Besides that we can see that the all the information are now write to the standard error stream.

4.10 New Page for “New API” and Improved “Deprecated” Page (tools/javadoc(tool))

With the Javadoc tool, you can generate a page summarizing the changes in the API. To list the recent releases you can specify the flag – – since in the command line. This flag is used to look after the tags with @since to be included in the result.

The –since-label command-line option provides text to use in the heading of the “New API” page. On the page that summarizes deprecated items, you can view items grouped by the release in which they were deprecated.

4.11 JEP 412: Foreign Function & Memory API (Incubator) (core-libs)

In the latest JDK release, a new API was added in which Java programs can interoperate with code and data outside of the JVM. To call efficiently and safely accessing foreign memory (memory not managed by JVM) the API gives you the possibility to call native libraries and process native data without the brittleness and danger of JNI. The JNI was replaced with a superior pure Java development model. Give you the possibility to operate on different kinds of foreign memory.

The Foreign Function & Memory API (FFM API) defines classes and interfaces so that client code in libraries and applications can:

  • Allocate foreign memory(MemorySegment, MemoryAddress, and SegmentAllocator),
  • Manipulate and access structured foreign memory (MemoryLayout MemoryHandles, and MemoryAccess)
  • Manage the lifecycle of foreign resources (ResourceScope)
  • Call foreign functions (SymbolLookup and CLinker).

This new implementation for this is in this package: jdk.incubator.foreign in the jdk.incubator.foreign module.

4.12 Console Charset API (core-libs)

In the java.io.Console a new method was created that returns the Charset for the console. The value return by default method that might be different depending on the platform where this method is called. For example on Windows (en-US) it will return windows-1252 while on other machines it might return: IBM437.

4.13 JDK Flight Recorder Event for Deserialization (core-libs/java.io:serialization)

To monitor the desensitization of objects you can now do it with JDK Flight Recorder. If JFR is enable and configured to include serialization events, JFR will emit an event whenever the running program attempts to deserialize an object. The event name is: jdk.Deserialization is disabled by default. If a filter is enable, the JFR event can indicate whether to accept or reject the deserialization of the object. For more information have a look at the  ObjectInputFilter, Monitoring deserialization to improve Application Security.

4.14 JEP 415: Implement Context-Specific Deserialization Filters (core-libs/java.io:serialization)

Allows applications to configure context-specific and dynamically-selected deserialization filters via a JVM-wide filter factory that is invoked to select a filter for each individual deserialization operation. For more examples about this, you can check out this link.

4.15 System Property for Native Character Encoding Name (core-libs/java.lang)

A new system property: native.encoding was added in this release. With this system property, you can set the character encoding name. For example, typically the value is UTF-8 for Linux and macOS platforms, and Cp1252 in Windows (en-US).

4.16 Add java.time.InstantSource (core-libs/java.time)

New interface java.time.InstantSource in JDK 17. This interface is an abstraction from java.time.Clock that only focuses on the current instant and does not refer to the time zone.

4.17 Hex Formatting and Parsing Utility (core-libs/java.util)

A new class java.util.HexFormat provides conversions to and from hexadecimal for primitive types and byte arrays. All the methods that you need like: delimiter, prefix, suffix, uppercase, or lowercase are provided by factory methods returned by HexFormat (this class is thread safe) For the deprecated and removed features, you can check out the last part of the release note.

public class ExampleHexFormattingAndParsing {

    public static void main(String[] args) {
        final HexFormat hexFormat = HexFormat.of().withPrefix("[").withSuffix("]").withDelimiter(", ");
        System.out.println(hexFormat.formatHex(new byte[]{0, 10, 20}));
    }
}

Simple example of HexFormat converting from decimal to hexa. The output for this class will be:

[00], [0a], [14]

5. Plans for the next releases

Java Corporation is planning to boost the functionality of this language and keep a continuous improvement with each 6 months release. The JDK is used on a large scale and Oracle wants to provide a better experience to developers with a robust and performant language.

For the next two versions (JDK 18 and 19) you can use the version from the early access release.

The plans for the next release is to group some JEP in some projects like: Loom, Valhalla, Panama and Metropolis. Oracle will keep the cadence of the release for JDK 18, 19, 20… at every 6 months.

If you want to search for all the tasks in the JDK 18 you can find out on their “Jira” platform. You can find it as well for JDK 19 by modifying the JQL.

A release page where you can find useful information: https://www.java.com/releases/.

Link to the Github repository: https://github.com/openjdk/jdk/.

To see all the proposed JSR (Java Specification Request), you can find out on the official Java Community Process.

6. Conclusion

In this article, we managed to give you a better understanding of JDK 17, the concept of LTS, OpenJDK, and Oracle JDK. The next features that Java wants to bring in the next implementation are a clear vision about the evolution of Java and the power of this language.

In this article there are some practical examples with the latest changes in JDK 17. This will help you to better understand the benefits of this new version.

For more information, you can check out the official website where you find the latest release note.

7. References

Iulian Timis

My name is Iulian and I graduated Faculty of Electronics, Telecommunications, and Information Technology. My master's degree was in Computer Science, Information Security. I am passionate about technology and the security area. During my career I was working as a Java Developer, on the backend and frontend side, sometimes doing some DevOps tasks.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button