Getting Started With Java 17


Java SE Platform version 17
Overview the key features and changes since Java 11 (with code examples), download the right production-ready builds of the JDK 17 and get to know the tooling support of Java 17 (Maven, Gradle, IntelliJ IDEA and Eclipse).

Introduction

JDK 17, the open-source reference implementation of Java SE Platform version 17, was released on 14 September 2021.

It will be considered a long-term support (LTS) release from most vendors, the previous version having this kind of support being JDK 11. You can overview the key features and changes from Java 8 to Java 11 in the following article.

Production-ready builds of JDK 17 can be downloaded from the following sources:

  • Eclipse Temurin (Eclipse Adoptium project, the continuation of the AdoptOpenJDK project): Provides prebuilt OpenJDK binaries using an open source build & test infrastructure, for more than 7 platforms (such as Linux, Windows, macOS, and Docker).

  • Azul Zulu: provides community as well as enhanced and certified builds of OpenJDK for a wide array of platforms.

  • Oracle JDK: Commercial Oracle branded builds of the JDK. Free for development use, and in special cases in production under the Oracle No-Fee Terms and Conditions License.

Key features since Java 11

Pattern Matching for instanceof

  // The following code in JDK 11:
  if (obj instanceof Double) {
    Double d = (Double) obj;
    System.out.println(d.intValue());
  }

  // can be expressed in JDK 17 as:
  if (obj instanceof Double d) {
    System.out.println(d.intValue());
  }

Records

  // The following code in JDK 11:
  public final class Point {
      private final int x;
      private final int y;

      public Point(int x, int y) {
          this.x = x;
          this.y = y;
      }

      public int getX() {
          return x;
      }

      public int getY() {
          return y;
      }

      @Override
      public boolean equals(Object o) {
          if (this == o) return true;
          if (o == null || getClass() != o.getClass()) return false;
          Point point = (Point) o;
          return x == point.x && y == point.y;
      }

      @Override
      public int hashCode() {
          return Objects.hash(x, y);
      }

      @Override
      public String toString() {
          return "Point{" + "x=" + x + ", y=" + y + '}';
      }
  }

  // can be expressed in JDK 17 as:
  record Point(int x, int y) { }

Sealed Classes

Sealed classes and interfaces restrict which other classes or interfaces may extend or implement them.

  public abstract sealed class Shape permits Circle, Triangle, Rectangle { ... }

Switch Expressions

Added a new switch label form case L -> that allows multiple values per case and does not fall through to the following cases (without needing a break statement)

  switch (day) {
    case MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY -> System.out.println("weekday");
    case SATURDAY, SUNDAY                             -> System.out.println("weekend");
  }

Switch expressions and yielding values:

  int daysOfMonth = switch (month) {
    case 2            -> {
      if (isLeapYear(year)) {
        yield 29;
      } else {
        yield 28;
      }
    }
    case 4, 6, 9, 11  -> 30;
    default           -> 31;
  };

Text Blocks

  String html = """
            <html>
              <body>
                <p>Hello, world</p>
              </body>
            </html>
            """;

Edwards-Curve Digital Signature Algorithm (EdDSA)

  import java.nio.charset.StandardCharsets;
  import java.security.*;

  // ...
  byte[] bytesToBeSigned = "my data".getBytes(StandardCharsets.UTF_8);

  // Generate a public and private key pair using the Ed25519 instantiation of the EdDSA algorithm
  KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("Ed25519");
  KeyPair keyPair = keyPairGenerator.generateKeyPair();

  // Signature using the private key
  Signature signature = Signature.getInstance("Ed25519");
  signature.initSign(keyPair.getPrivate());
  signature.update(bytesToBeSigned);
  byte[] signatureBytes = signature.sign();

Hidden Classes

A hidden class is created by invoking Lookup::defineHiddenClass.

  import java.lang.invoke.MethodHandles;
  import java.lang.invoke.MethodHandles.Lookup.ClassOption;

  // ...
  MethodHandles.privateLookupIn(myClass, MethodHandles.lookup())
                .defineHiddenClass(bytes, false, ClassOption.NESTMATE, ClassOption.STRONG);

JVM Constants API

The java.lang.constant package provides nominal descriptors for runtime and classfile entities such as classes and method handles.

JVM, internals and removals


Tooling support for Java 17

Maven

The maven-compiler-plugin support Java 17 compilation using the following configuration in the pom.xml:

  <properties
      <maven.compiler.source>17</maven.compiler.source>
      <maven.compiler.target>17</maven.compiler.target>
      <!-- ... -->
  </properties>

or

  <build>
    <!-- ... -->
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.8.1</version>
        <configuration>
          <source>17</source>
          <target>17</target>
        </configuration>
      </plugin>
    </plugins>
  </build>

Gradle

Gradle does not yet support Java 17, but you can build your Java 17 project by using toolchains in your build.gradle:

  java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(17)
    }
  }

IntelliJ IDEA

IntelliJ IDEA 2021.2.1 adds basic support for Java 17, more improvements will follow in future releases.

Eclipse

Eclipse can support Java 17 starting from the 2021-09 (4.21) release.