Last Updated on September 19, 2023 by KnownSense
Java 17 LTS is the latest release providing long-term support for the Java SE platform. According to the Oracle No-Fee Terms and Conditions License, JDK 17 binaries are permissible for use in production and can be redistributed without any associated costs. The abbreviation “LTS” denotes “long-term support,” and this release is slated for availability on September 15, 2021.
An Open LTS variant of JDK 17 is presently accessible for crafting web and desktop applications. This version encompasses development tools, an assortment of libraries, a Java virtual machine, and other files. Embracing the evolving landscape and regular updates is imperative for adapting to and comprehending the nuances of the new version.
We all eagerly anticipate substantial improvements in this version to enhance our workflow. However, developers might feel disappointed since there aren’t any major release upgrades akin to what we commonly see in the JDK Enhancement Proposal (JEPS), as detailed below:
- Restore or Rebuild the “Always-Strict Floating-Point” Semantics
- Enhanced faster the “pseudo-Random” Number Generators
- New macOS rendering pipelines
- macOS/AArch64 Port
- Dismiss the Applet API for Removal
- JDK Internals Encapsulate strongly
- Switch Pattern Matching (Preview)
- Activation of the Removal RMI
- Generate sealed Classes
- Removal of the Experimental AOT and JIT Compiler
- Remove the Security Manager.
- Foreign Functions and Memory API (Incubator)
- Vector API (Second Incubator)
- Deserialization Filters Based on Context (content-specific)
We believe there haven’t been significant markup changes in this version, but we’re conducting a more thorough examination to gain a better understanding. Consequently, we’ve categorized them as follows:
- Nice developer-related features
- Developer-specific information or features
- Keeping current with Apple-related features
- Cleaning up various features
Let’s deep dive in each changes
Nice developer-related features
Switch Pattern Matching
It allows developers to simplify the code for switch statements that involve pattern matching. This feature provides a concise and more readable syntax to handle multiple conditions in switch statements.
Note: case statements can now be written as `case …expression ->’ instead of ‘case expression:’ since Java 12.
Traditional Switch statement:
public static String getDayOfWeek(int dayNum) {
String day;
switch (dayNum) {
case 1:
day = "Monday";
break;
case 2:
day = "Tuesday";
break;
case 3:
day = "Wednesday";
break;
case 4:
day = "Thursday";
break;
case 5:
day = "Friday";
break;
case 6:
day = "Saturday";
break;
case 7:
day = "Sunday";
break;
default:
day = "Invalid day";
}
return day;
}
Switch Statements Since Java 12
public static String getDayOfWeek(int dayNum) {
return switch (dayNum) {
case 1 -> "Monday";
case 2 -> "Tuesday";
case 3 -> "Wednesday";
case 4 -> "Thursday";
case 5 -> "Friday";
case 6 -> "Saturday";
case 7 -> "Sunday";
default -> "Invalid day";
};
}
Switch Statements Since Java 17
In addition to using constant patterns, the new feature of java 17 also allows developers to use variable patterns and type patterns.
Here is an example that demonstrates the use of variable and type patterns:
public static int getLength(Object obj) {
return switch (obj) {
case String s -> s.length(); // variable pattern
case List list && !list.isEmpty() -> list.size(); // type pattern
case null -> 0;
default -> -1;
};
}
Switch expressions in Java have two primary patterns:
Guarded pattern: Utilizes pattern && boolean expression for further refinement.
Suppose we have a program that categorizes people into two groups based on their age: “Young” and “Adult.” We can use a switch statement with a guarded pattern to achieve this:
int age = 25; // Assume the age of a person is 25
String category = switch (age) {
case int x when x < 18 -> "Young"; // Guarded pattern checks if age is less than 18
case int x -> "Adult"; // Default pattern, for ages 18 and above
};
System.out.println("Category: " + category);
In this example, we’re using the guarded pattern with the when
keyword to check if the age is less than 18. If the condition (x < 18
) is met, the “Young” category is assigned; otherwise, the default pattern assigns “Adult.” The age
variable is set to 25, so the output will be:
Category: Adult
Pattern enclosed in parentheses
Suppose we have a list of strings representing different types of fruits, and we want to categorize them into two groups: “Citrus Fruits” and “Other Fruits.” We can use a switch statement with patterns enclosed in parentheses to achieve this:
String fruit = "Orange"; // Assume we have a fruit called "Orange"
String category = switch (fruit) {
case "Orange", "Lemon", "Lime" -> "Citrus Fruits"; // Patterns enclosed in parentheses
default -> "Other Fruits";
};
System.out.println(fruit + " belongs to the category: " + category);
In this example, we have a switch statement with a pattern enclosed in parentheses within the first case. This pattern checks if the fruit
variable matches any of the specified citrus fruits (“Orange,” “Lemon,” or “Lime”). If it matches, it assigns the “Citrus Fruits” category; otherwise, it falls back to the default pattern, which assigns “Other Fruits.”
Since the fruit variable is set to “Orange” in this case, the output will be:
Orange belongs to the category: Citrus Fruits
Generate sealed Classes
This addition introduces sealed classes and interfaces to Java, enhancing language functionality. Sealed classes and interfaces restrict which other classes and interfaces can extend or implement them, respectively. This improvement, combined with JEP 406, enhances type checking, casting, and code pattern handling.
public abstract sealed class Subjects permits English, Maths, Science {...}
Developer-specific information or features
Restore or Rebuild the “Always-Strict Floating-Point” Semantics
This JEP aims to make floating-point operations consistently stringent, particularly benefiting scientific applications. Both default floating-point operations, strict or strictfp, yield identical results for floating-point calculations across all platforms.
For example, consider a scenario where a Java program needs to perform complex financial calculations that rely on precise floating-point arithmetic. In the past, there might have been instances where the results of these calculations varied slightly depending on the underlying hardware or JVM (Java Virtual Machine). To address this, Java “restore or rebuild” the “always-strict floating-point semantics” to ensure that the results of these calculations are consistent and predictable across different environments.
Vector API (Second Incubator)
The Vector API supports Single Instruction, Multiple Data (SIMD) operations, allowing multiple sets of instructions to be processed concurrently. It leverages specialized CPU hardware with vector instructions, enabling efficient code execution and utilization of underlying hardware capabilities.
Here’s a simplified example to illustrate the Vector API concept:
import jdk.incubator.vector.FloatVector;
import jdk.incubator.vector.VectorOperators;
public class VectorAPIDemo {
public static void main(String[] args) {
int vectorSize = FloatVector.SPECIES_256.length();
float[] data1 = new float[vectorSize];
float[] data2 = new float[vectorSize];
float[] result = new float[vectorSize];
// Initialize the data arrays
for (int i = 0; i < vectorSize; i++) {
data1[i] = i + 1.0f;
data2[i] = (i + 1.0f) * 2;
}
// Create FloatVectors from the data arrays
FloatVector vector1 = FloatVector.fromArray(FloatVector.SPECIES_256, data1, 0);
FloatVector vector2 = FloatVector.fromArray(FloatVector.SPECIES_256, data2, 0);
// Perform element-wise addition using the Vector API
FloatVector resultVector = vector1.add(vector2, VectorOperators.ADD);
// Store the result in an array
resultVector.intoArray(result, 0);
// Display the result
for (int i = 0; i < vectorSize; i++) {
System.out.println("Result[" + i + "] = " + result[i]);
}
}
}
In this example, the Vector API allows us to perform element-wise addition of two arrays in a highly efficient manner by leveraging vectorized instructions provided by the CPU, resulting in improved performance for large datasets. It’s important to note that the Vector API is particularly beneficial for operations involving large arrays or matrices, where parallelization can lead to significant speedups.
Deserialization Filters Based on Context (Content-specific)
Starting with JDK 9, this feature allows verification of serialized data received from untrusted sources, addressing common security concerns. Applications can dynamically configure context-specific deserialization filters.
Enhanced “Pseudo-Random” Number Generators
This enhancement introduces a new interface and solutions for pseudo-random number generators, simplifying the use of multiple PRNG algorithms and supporting stream-based operations more effectively.
click here for more details.
JDK Internals Encapsulation
JEP 403 eliminates the -illegal-access flag, emphasizing stronger encapsulation of JDK internals. When the flag is present and disregarded by the platform, a console message advises against its usage.
Foreign Functions and Memory API (Incubator)
Java programmers gain the ability to access code from outside the JVM, controlling memory beyond the heap. This API aims to replace the JNI API, offering improved performance and security.
Keeping current with Apple-related features
New macOS Rendering Pipelines
This JEP establishes a Java 2D internal processing pipeline for macOS, addressing the removal of the OpenGL API in macOS 10.14. The implementation uses the Apple Metal API while preserving existing APIs.
macOS/AArch64 Port
In alignment with Apple’s strategy to transition to AArch64, this JEP enables the JDK to run on macOS platforms with AArch64 architecture.
Cleaning up Various Features
Discontinuation of the Applet API
Most browsers no longer support the deprecated applet API, rendering its removal necessary.
RMI Activation Removal
The RMI activation mechanism is outdated and is being deactivated due to its declining use in web technology over the past decade.
Removal of Experimental AOT and JIT Compiler
Experimental versions of the java-based AOT (ahead-of-time) and JIT (just-in-time) compilers are being removed.
Security Manager Deprecation
The Security Manager, which was originally introduced in Java 1.0, is marked for removal in a future update. An annotation-based syntax is provided for its removal.
Conclusion
Java 17 introduces a plethora of features catering to both users and developers, simplifying the development of complex web-based and Java-based applications. These changes encompass numerous additions and removals, ultimately contributing to a more robust development environment.