Top 5 Features of Java 17 That You Must Know

Change is the only constant thing and according to Darwin’s Theory of Survival of the fittest, the individual who adapts to the evolving world will sustain itself in the long run. Looks like this theory is true for Java also, as it is continuously evolving and serving for more than two decades. From JDK 1.0 to Java 17 (LTS) it has come a long way. Java 17 is the latest long-term support (LTS) release for the SE platform. It was released on September 15, 2021, and has come up with a package of features that we shouldn’t let go unexplored.


Adding features in any programming language improve its performance and thus makes code complexity easy. For example, C# was initially a Java clone but adding more features to it gave birth to C#. While there are many features that are introduced in Java 17, let’s talk about a few of them. In this article, we’re going to discuss the Top 5 features of Java 17.

1. Restricting the implementation with sealed classes and Interfaces

Sealed classes were a preview feature in JDK 15 and now they have come as a full feature in JDK 17. When inheritance was introduced, there was a mixed opinion of people as it didn’t restrict the number of implementations. Sealed classes bring an end to this as it is a feature with which one can restrict the implementations. To cut to the chase, sealed classes give us the privilege of controlling which classes or models can implement or extend that interface or class arrangement. It represents restricted class hierarchies that provide control over an inheritance. For a sealed class, all direct subclasses need to be known at compile-time and third-party clients can’t extend a sealed class in their code. To make a Java class, a sealed Java classadd the sealed modifier to its declaration, and keyword permits are placed to indicate the classes which are permitted for the given sealed class.

Sealed class Fruit specifies three permitted subclasses, Square, Rectangle, and Circle:

package com.geeksforgeeks.example.figures

public sealed class shape permits, Square, Rectangle, Circle { }

2. Using Null in Switch Case is Now Legal

Previously, keeping selector expression as null in switch statement and expression used to throw a NullPointerException and we essentially have to throw a Null Pointer Exception to be on a safer side. To resolve this issue, Java 17 has come up with a feature where we can put null as a selector expression in switch case expressions. Consider the below example where we can pass null as a selector expression.

switch(checkNumber) {

case 1,7 -> System.out.println(“odd number”) ;

case 2,8 -> System.out.println(“even number”) ;

case null -> System.out.println(“Not defined”) ;

default -> System.out.println(“not a number”) ;


Here, checkNumber variable gets a number as an input. If null is passed as an input, “Not defined” is displayed as an output. Note that, for case 1,7 and case 2,8, other odd and even numbers are to be taken in selector expression as well for the proper functioning of the code. Only a few are taken to maintain the simplicity of the example.

3. End of Guessing the Cause of Null Pointer Exception

Be it working with linked lists or just a fragment of code having reference to an object, there is always a risk of reference to a null object which can get things to ground zero if not handled well. Debugging and Java logs can help but debugging itself is a time taking task and java logs are not that good at providing details about the culprit object which caused the NullPointerException. Here, the NullPointerException guidance feature of Java 17 comes as a friend indeed as it provides the exact name of the variable that is null from the exception’s stack trace. Thus, this feature saves us from debugging hassle and ends up the guessing game of finding out the pointer which went null.

4. Redefining Switch Statement Expressions

Forgetting a single break among multiple lines of switch-case statements is not at all a welcomed guest. Moreover, the case-break-case-break pattern doesn’t seem to be a good deal when dealing with many switch cases. Yes, now we don’t have to break with the frequent use of break! Java addressed our concern and here we present the new switch statement expressions in Java 17. The new switch expressions are less error-prone as it is cleaner and simpler now. The use of arrow symbols not only eliminates the fall-through functionality but also makes it more readable and easy to debug.

We can include more than one value in the same block by comma separating them. One of the important features is the introduction of the yield keyword. In the code snippet, on the execution of the default statement, System.out.println() will execute and the identifyTyres variable will end up to be “Unknown Vehicle” because this is what the default is meant to yield.

String identifyTyres = switch (vehicle) {

case Car -> “four”;

case Bike, Cycle -> “two”;

case Autorickshaw -> “three”;

default -> { System.out.println(“The vehicle could not be found.”);

yield “Unknown Vehicle”;


5. Reducing Lines of Code with Record Classes

Record classes were previewed in Java 14. The complex and ugliest POJO code looks nicer when implemented with Records. They are both immutable and final. The fields of the Record cannot be changed after creation and the extension of the Records class is also not allowed. They are rightly the data-only classes that manage the boilerplate code of POJOs. Records are very useful when all we want is to temporarily hold immutable data. In the code snippet, Data is a record and the a and b are referred to as components of the Data record. On defining a record, we get an equals() method, hashcode() method already implemented, and a toString() method implementation to print the record components along with the component names.

record Data(long a, long b) { }

The above Record Data is equivalent to the following lines of code:

public final class Data {

private final long a;

private final long b;

Public Data(long a, long b) {

this.a = a;

this.b = b;


long a() { return this.a; }

long b() { return this.b; }

// Implementation of equals() and hashCode(), which specify

public boolean equals…

public int hashCode…

// An implementation of toString() that returns a string

public String toString() {…}


The above mentioned are the Top 5 features of Java 17 LTE. Click here Ito explore more cool features of Java 17. Let’s admit that we are always keen on new features, be it mobile phones, television, washing machines, and whatnot. Java is no less in this case and it always amazes us with the improvements and introduction of new features. Experimenting with new features in Java code not only enhances our knowledge in the field of Java but also keeps us motivated to learn and upskill ourselves. Java 17 LTE is a big thumbs up as these features are acceptable and make tasks easier for Java developers.

Leave a Comment