Java 17, released in September 2021, is a Long-Term Support (LTS) version, bringing stability, performance, and several key language and library enhancements. This guide provides a detailed explanation of all the new features, their significance, and examples.
1. Sealed Classes
What Are Sealed Classes?
Sealed classes restrict which other classes or interfaces can extend or implement them. This ensures controlled inheritance and provides more predictable class hierarchies.
Why Was It Introduced?
- Improves encapsulation.
- Reduces unintended subclassing.
- Simplifies pattern matching and switch expressions.
Example
Define a sealed class:
public sealed class Vehicle permits Car, Truck {}
public final class Car extends Vehicle {}
public final class Truck extends Vehicle {}
Using pattern matching with sealed classes:
void process(Vehicle vehicle) {
if (vehicle instanceof Car car) {
System.out.println("Car: " + car);
} else if (vehicle instanceof Truck truck) {
System.out.println("Truck: " + truck);
}
}
Benefits
- Provides compile-time safety by limiting subclassing.
- Simplifies pattern matching scenarios.
Limitations
- Requires explicit permissions using
permits. - May need refactoring for existing hierarchies.
2. Pattern Matching for switch (Preview)
What Is It?
Allows switch statements to handle multiple patterns and types in a more concise and expressive way.
Why Was It Introduced?
- Simplifies type-specific operations.
- Reduces boilerplate in
switchstatements.
Example
void test(Object obj) {
switch (obj) {
case String s -> System.out.println("String: " + s);
case Integer i -> System.out.println("Integer: " + i);
case null -> System.out.println("Null value");
default -> System.out.println("Unknown type");
}
}
Benefits
- Cleaner, type-safe
switchlogic. - Supports modern functional-style programming.
Limitations
- Still a preview feature (needs enabling).
3. Record Enhancements
What Are They?
Records now support local declarations and can be used in methods, constructors, or blocks.
Why Was It Introduced?
- Enhances usability of records for temporary or inline structures.
Example
void process() {
record Point(int x, int y) {}
Point point = new Point(10, 20);
System.out.println(point.x() + ", " + point.y());
}
Benefits
- Reduces verbosity for temporary data holders.
Limitations
- Only suitable for immutable data.
What Was Allowed in Java 16
- Top-level records (in their own file or as a public record)
- Static nested records inside a class
// ✅ Top-level record (Java 16)
public record Person(String name, int age) {}
// ✅ Static nested record (Java 16)
public class Container {
static record Data(String key, String value) {}
}
❌ What Was Not Allowed in Java 16
Trying to declare a record inside a method, constructor, or block would fail:
public class ExampleJava16 {
public void method() {
// ❌ Compile error in Java 16
record Temp(String data) {}
}
}
Error in Java 16:
cssCopyEditRecords cannot be declared in a method, constructor, or initializer block
🆕 In Java 17
The restriction was lifted, and now local record declarations are allowed, just like this:
public class ExampleJava17 {
public void method() {
record Temp(String data) {} // ✅ Legal in Java 17+
Temp t = new Temp("sample");
System.out.println(t.data());
}
}
📌 Summary Table
| Feature | Java 16 | Java 17 |
|---|---|---|
| Top-level records | ✅ Allowed | ✅ Allowed |
| Static nested records | ✅ Allowed | ✅ Allowed |
| Local records (in method) | ❌ Not allowed | ✅ Allowed |
4. Text Blocks Become Standard
What Are They?
Text blocks, introduced in earlier versions, are now finalized in Java 17. They simplify working with multi-line strings.
Why Was It Introduced?
- Reduces boilerplate when dealing with multi-line text.
- Improves readability for SQL queries, JSON, XML, etc.
Example
String query = """
SELECT * FROM users
WHERE id = 1
""";
System.out.println(query);
Benefits
- Simplifies text formatting.
- Eliminates the need for escape sequences in multi-line strings.
5. JEP 356: Enhanced Pseudo-Random Number Generators
What Is It?
Java 17 introduces new interfaces and implementations for random number generation under java.util.random.
Why Was It Introduced?
- Adds more flexible random generators (e.g., LCG, Xoshiro, SplitMix).
- Provides support for deterministic random streams.
Example
RandomGenerator generator = RandomGeneratorFactory.of("Xoshiro256PlusPlus").create();
System.out.println(generator.nextInt());
Benefits
- Better support for high-performance applications.
- Extends randomness APIs for scientific computing.
🔙 Before Java 17
You typically used these classes:
java.util.Randomjava.security.SecureRandomThreadLocalRandom
Example:
import java.util.Random;
Random random = new Random();
int num = random.nextInt(100); // 0 to 99
Limitations:
Randomis not cryptographically secure.- Not easily testable or extensible.
- Not much control over random algorithms.
- Not thread-safe (unless using
ThreadLocalRandom).
🚀 Java 17 Enhancements (New java.util.random package)
Java 17 introduced:
- New interfaces:
RandomGeneratorRandomGenerator.ArbitrarilyJumpableGeneratorRandomGenerator.LeapableGeneratorRandomGenerator.SplittableGenerator
- New implementations:
L32X64MixRandomL64X128MixRandomXoroshiro128PlusPlusXoshiro256PlusPlusSplittableRandom, etc.
✅ Example with new API:
import java.util.random.RandomGenerator;
import java.util.random.RandomGeneratorFactory;
public class RandomExample {
public static void main(String[] args) {
RandomGenerator rng = RandomGenerator.of("L64X128MixRandom");
int num = rng.nextInt(100);
System.out.println("Generated: " + num);
}
}
🔍 Benefits:
- More efficient and modern algorithms.
- Deterministic and reproducible random sequences.
- Better support for parallel streams (
SplittableGenerator). - Suitable for scientific and simulation workloads.
- You can even choose the algorithm by name!
📌 Summary Table:
| Feature | Pre-Java 17 | Java 17+ |
|---|---|---|
| Common RNG classes | Random, SecureRandom | New interfaces + algorithmic classes |
| Extensibility | Limited | Easy to extend and plug new algorithms |
| Algorithm choice | Hidden, not configurable | Configurable with RandomGenerator.of |
| Performance (thread-safe use cases) | Use ThreadLocalRandom | Better with SplittableGenerator |
| Use in parallel computation | Tricky | Built-in support with Splittable |
6. Strong Encapsulation of JDK Internals
What Is It?
All internal APIs in the sun.* packages are now strongly encapsulated, accessible only via reflection or command-line options.
Why Was It Introduced?
- Increases security and encourages use of standard APIs.
- Reduces reliance on unstable internal implementations.
Impact
Developers must migrate to public alternatives for internal APIs like sun.misc.Unsafe.
7. Removal of Deprecated Features
What Was Removed?
- RMI Activation: Remote Method Invocation’s activation system is removed.
- Applet API: Applets are now fully removed due to obsolescence.
- Thread Destroy Methods: Methods like
Thread.stop()were removed for safety concerns.
Impact
Older applications relying on these features need significant migration efforts.
8. JEP 382: New macOS Rendering Pipeline
What Is It?
Java 17 replaces the old rendering pipeline with Metal, Apple’s modern graphics API.
Why Was It Introduced?
- Aligns with Apple’s deprecation of OpenGL.
- Improves graphics rendering performance on macOS.
Impact
Developers targeting macOS benefit from better performance and compatibility.
9. Deprecation of SecurityManager
What Is It?
The SecurityManager API is deprecated and will be removed in a future version.
Why Was It Deprecated?
- Outdated and rarely used.
- Replaced by more modern sandboxing mechanisms.
10. Foreign Function & Memory API (Preview)
What Is It?
Allows Java programs to interact with native code and memory efficiently.
Why Was It Introduced?
- Provides a modern alternative to JNI (Java Native Interface).
Example
MemorySegment segment = MemorySegment.allocateNative(1024);
segment.set(ValueLayout.JAVA_INT, 0, 42);
Benefits
- Simplifies interoperation with C libraries.
- Improves performance for memory-intensive applications.
11. Context-Specific Deserialization Filters
What Is It?
Introduces filters for deserialization operations to improve security.
Why Was It Introduced?
- Prevents vulnerabilities caused by insecure deserialization.
Example
ObjectInputFilter filter = ObjectInputFilter.Config.createFilter("java.util.*;!*");
ObjectInputStream in = new ObjectInputStream(new FileInputStream("data.obj"));
in.setObjectInputFilter(filter);
Benefits
- Provides fine-grained control over serialization.
12. Performance Enhancements
- Garbage Collection: G1 and ZGC improvements for better throughput and latency.
- Thread-Locale Handshakes: Reduce thread pauses during garbage collection.
13. JEP 306: Restore Always-Strict Floating-Point Semantics
What Is It?
Java 17 enforces strict floating-point calculations for better predictability.
Impact
Improves consistency across platforms.
🔙 Before Java 17 (Java 16 and earlier)
- Java had an optional
strictfpkeyword to enforce strict IEEE 754 floating-point behavior. - Without
strictfp, the compiler and JVM could optimize floating-point calculations for performance, potentially sacrificing precision or portability.
Example:
class LooseFloat {
public static double compute() {
double a = 1.0e300;
double b = 1.0e-300;
return a * b;
}
}
- Depending on platform and compiler, results could vary slightly due to extended precision used by some CPUs (like x87 floating point on x86).
✅ Java 17 and Beyond
- Java 17 enforces stricter floating-point calculations globally, aiming for better predictability and consistency across platforms.
- It narrows the gap between behavior with and without
strictfp, especially instrict modeJVM configurations or newer compiler targets.
Key Change:
- Compilers and JVMs now more consistently adhere to IEEE 754 standards, even if
strictfpis not used explicitly in many cases.
✅ Example (Java 17 with strict predictability):
public strictfp class StrictFloat {
public static double compute() {
double a = 1.0e300;
double b = 1.0e-300;
return a * b; // Result is strictly predictable
}
}
Even without strictfp, the result will likely follow strict behavior because the JVM and JDK toolchain have been tightened.
📌 Summary Table:
| Feature | Before Java 17 | Java 17+ |
|---|---|---|
| Floating-point behavior | Can be platform/JVM dependent | More consistent and predictable |
strictfp needed? | Yes, for strict IEEE 754 compliance | Mostly enforced by default (depending on mode) |
| Cross-platform consistency | May vary | More uniform |
14. Unified Logging Enhancements
What Is It?
Improved logging options for JVM events and diagnostics using Unified Logging.
15. JEP 391: macOS AArch64 Support
What Is It?
Adds support for macOS running on Apple Silicon (ARM-based M1 chips).
Why Was It Introduced?
- Aligns with Apple’s transition to ARM-based processors.
Benefits
- Optimized for the latest Apple hardware.
Benefits of Java 17
- Long-Term Support: Reliable for enterprise adoption.
- Modern Features: Sealed classes, records, pattern matching.
- Enhanced Security: Strong encapsulation and deserialization filters.
- Performance Gains: Improved GC and native interoperability.
Disadvantages
- Migration effort for deprecated APIs.
- Some features like
SecurityManagerremoval can disrupt legacy applications.
Java 17 is a robust and future-proof release, catering to modern development needs with enhanced performance, security, and language capabilities