Java 17 feature

Java 17 was released in September 2021 and it comes with several new features and improvements. In this blog, we will take a closer look at some of the most notable features of Java 17. 

Sealed Classes (JEP 409) 

Sealed classes are a new type of class introduced in Java 17. They provide more control over inheritance by restricting the number of subclasses that can extend a class. Sealed classes help to prevent unauthorized extensions of a class and make code more secure and maintainable. 

CODE SNIPPET— 

public sealed class Shape permits Circle, Square { 

protected double area; 

public double getArea() { 

return area; 





final class Circle extends Shape { 

private final double radius; 

public Circle(double radius) { 

this.radius = radius; 

area = Math.PI * radius * radius; 



public double getRadius() { 

return radius; 





final class Square extends Shape { 

private final double side; 

public Square(double side) { 

this.side = side; 

area = side * side; 



public double getSide() { 

return side; 



}

public class Main { 

public static void main(String[] args) { 

Shape circle = new Circle(5); 

System.out.println("Circle area: " + circle.getArea()); 

System.out.println("Circle radius: " + ((Circle) circle).getRadius()); 

Shape square = new Square(4); 

System.out.println("Square area: " + square.getArea()); 

System.out.println("Square side: " + ((Square) square).getSide()); 





Pattern Matching for switch (JEP 406) 

Java 17 introduces pattern matching for switch statements. This allows developers to match and extract values from patterns in switch expressions. It simplifies code and reduces the need for additional conditional statements. 

CODE SNIPPET— 

public class Main { 

public static void main(String[] args) { 

Object obj = "Hello, World!"; 

int result = switch (obj) { 

case String s && s.length() > 10 -> { 

System.out.println("String is longer than 10 characters"); 

yield s.length(); 



case String s -> { 

System.out.println("String is shorter than or equal to 10 characters"); 

yield s.length(); 



case Integer i -> { 

System.out.println("Object is an integer"); 

yield i; 



default -> { 

System.out.println("Object is of an unknown type"); 

yield -1; 

}

}; 

System.out.println("Result: " + result); 



Enhanced Pseudo-Random Number Generators (JEP 356) 

Java 17 enhances the existing pseudo-random number generators by introducing three new algorithms: LXM, PCG, and XoShiRo. These new algorithms are faster and provide better-quality random numbers. 

CODE SNIPPET— 

import java.security.SecureRandom; 

public class Main { 

public static void main(String[] args) { 

SecureRandom secureRandom = new SecureRandom(); 

byte[] randomBytes = new byte[16]; 

// Generating random bytes using the default algorithm 

secureRandom.nextBytes(randomBytes); 

System.out.println("Random bytes generated using the default algorithm:"); for (byte b : randomBytes) { 

System.out.print(b + " "); 



System.out.println("\n"); 

// Generating random bytes using SHA-512/256 algorithm 

secureRandom = SecureRandom.getInstance("SHA512/256PRNG"); 

secureRandom.nextBytes(randomBytes); 

System.out.println("Random bytes generated using the SHA-512/256 algorithm:"); for (byte b : randomBytes) { 

System.out.print(b + " "); 



System.out.println("\n"); 

// Generating random bytes using SHA3-224 algorithm 

secureRandom = SecureRandom.getInstance("SHA3-224PRNG"); 

secureRandom.nextBytes(randomBytes); 

System.out.println("Random bytes generated using the SHA3-224 algorithm:");

for (byte b : randomBytes) { 

System.out.print(b + " "); 



System.out.println("\n"); 

// Generating random bytes using SHA3-256 algorithm 

secureRandom = SecureRandom.getInstance("SHA3-256PRNG"); 

secureRandom.nextBytes(randomBytes); 

System.out.println("Random bytes generated using the SHA3-256 algorithm:"); for (byte b : randomBytes) { 

System.out.print(b + " "); 



System.out.println("\n"); 

// Generating random bytes using SHA3-384 algorithm 

secureRandom = SecureRandom.getInstance("SHA3-384PRNG"); 

secureRandom.nextBytes(randomBytes); 

System.out.println("Random bytes generated using the SHA3-384 algorithm:"); for (byte b : randomBytes) { 

System.out.print(b + " "); 



System.out.println("\n"); 



Strongly Encapsulate JDK Internals by Default (JEP 403) 

In Java 17, JDK internals are now strongly encapsulated by default. This means that only internal APIs that are explicitly exported are accessible. This enhances the security of Java applications and makes them less vulnerable to external attacks. 

CODE SNIPPET— 

public class Main { 

public static void main(String[] args) { 

sun.misc.Unsafe unsafe = sun.misc.Unsafe.getUnsafe(); // Compilation error 

// Uncomment the following line to access the Unsafe class using the --illegal-access command-line option 

// System.setProperty("illegal-access", "permit"); 

// Uncomment the following line to access the Unsafe class using the 

jdk.unsupported.allow.restricted.packages system property 

// System.setProperty("jdk.unsupported.allow.restricted.packages", "true");

int size = unsafe.addressSize(); 

System.out.println("Address size: " + size); 



Improved UTF-8 support (JEP 400) 

Java 17 improves the performance of the UTF-8 encoding and decoding operations by making use of the recently introduced JDK 16’s implementation of UTF-8 strings. 

CODE SNIPPET— 

import java.nio.charset.StandardCharsets; 

import java.util.Arrays; 

public class Main { 

public static void main(String[] args) { 

String s = "ABCD"; 

byte[] bytes = s.getBytes(StandardCharsets.UTF_8); 

System.out.println(Arrays.toString(bytes)); 



Deprecate the Applet API for Removal (JEP 398) 

The Applet API has been deprecated in Java 17 and will be removed in a future release. This is due to security concerns and the decreasing usage of the Applet API. 

CODE SNIPPET— 

import java.applet.Applet; 

public class Main { 

public static void main(String[] args) { 

// Create a new instance of the deprecated Applet class 

Applet applet = new Applet(); 

System.out.println(applet); 



}

Foreign Function and Memory API (Incubator) (JEP 389) 

The Foreign Function and Memory API (Incubator) provides a way to call native code from Java and access native memory. It is still in the incubator phase and is not recommended for use in production environments. 

CODE SNIPPET— 

import jdk.incubator.foreign.*; 

import static jdk.incubator.foreign.CLinker.*; 

public class ExampleProgram { 

public static void main(String[] args) { 

try (var scope = ResourceScope.newConfinedScope()) { 

// Load the C library and define the function signature 

LibraryLoader loader = LibraryLoader.ofSystem(); 

var math = loader.load("m"); 

FunctionDescriptor sinDescriptor = FunctionDescriptor.of(CLinker.C_LONG_DOUBLE, CLinker.C_LONG_DOUBLE); 

// Get a function pointer for the sin() function 

var sinFn = math.lookup("sin").get().address(); 

// Allocate a buffer to hold the argument and result 

var buf = scope.allocate(C_LONG_DOUBLE, 1); 

// Set the argument value 

buf.setDouble(0, Math.PI / 2); 

// Call the sin() function and print the result 

var result = sinFn.invoke(C_LONG_DOUBLE, buf); 

System.out.println("sin(π/2) = " + result.getDouble(0)); 





}

In conclusion, Java 17 introduces several new features and improvements that make the development of Java applications more efficient, secure, and maintainable. Sealed classes and pattern matching for switches are two significant additions that will help developers to write cleaner and more secure code. Other features such as enhanced pseudo-random number generators, improved UTF-8 support, and strongly encapsulated JDK internals by default further enhance the functionality and security of Java applications.

Leave a Reply