Java version 17 brought some changes to Java but also made many developers reconsider their desire to move to other JVM languages. The most noticeable changes were made in the direction of modernizing the Java code and adding new language constructs to simplify it. Of course, the matter was not without changes to the Java core, which made Java even more efficient.
Text Blocks
The Text Block feature has finally appeared in Java. I am sure that this is one of the changes that Java programmers had been waiting for a very long time. Now, you can forget about long compound lines that are hard to read. Text blocks allow you to write multiline text in the most convenient way. Inside such a block, you can compose the text how you want to see it, and you can still use escape sequences for more precise formatting.
From our partners:
Java 11. String Escape Sequences:
public String poem = " " +
"Twinkle, Twinkle, Little Star\n" +
" \n" +
" Twinkle, twinkle, little star,\n" +
" How I wonder what you are!\n" +
" Up above the world so high,\n" +
" Like a diamond in the sky.\n" +
" \n" +
" Twinkle, twinkle, little star,\n" +
" How I wonder what you are!";
Java 17. Text Block:
public String poem = """
Twinkle, Twinkle, Little Star
Twinkle, twinkle, little star,
How I wonder what you are!
Up above the world so high,
Like a diamond in the sky.
Twinkle, twinkle, little star,
How I wonder what you are!
""";
Records
Another update that is slowly making the Java language more usable is Records. Previously, to create a class, we needed to describe the class, specify its fields, and add necessary methods such as equals, hashcode, getters, and setters. All of this has now become unnecessary since Records appeared. Records allow you to create data-safe classes by specifying only the required fields; all other methods will be created automatically. However, it is worth remembering that Records act as a data class and were created to store data, not to perform various actions. Records are thread-safe because all Record fields are final. The last important thing to know is that the generated method for getting the value of a field will not contain ‘get’ as it would in classic Java Beans.
Java 11. Data Class:
public class DataClass {
public DataClass (Integer id, String name) {
this.id = id;
this.name = name;
}
private final Integer id;
private final String name;
public Integer getId() {
return id;
}
public String getName() {
return name;
}
@Override
public boolean equals(Object o) {
...
}
@Override
public int hashCode() {
...
}
}
Java 17. Record:
public record DataClass(Integer id, String name) {
}
The difference is obvious: while performing the same functions, creating Records requires significantly fewer lines of code.
New Switch Expressions
The list of changes also includes Switch Expressions. The changes affected not only the syntax of Switch Expressions, which made their writing more concise but also the functionality. Switch Expressions now return the result of an iteration, making it even easier to write code and make it even more concise. New Switch Expressions no longer require a break
after each case
.
Java 11. Switch Expression:
public String getSeasonDescription(Season season) {
String seasonDescription;
switch (season) {
case SPRING:
seasonDescription = "Flowers are blooming!";
break;
case SUMMER:
seasonDescription = "It's hot outside!";
break;
case AUTUMN:
seasonDescription = "Leaves are falling!";
break;
case WINTER:
seasonDescription = "Snow is coming!";
break;
default:
throw new IllegalStateException("Invalid season: " + season);
}
return seasonDescription;
}
Java 17. Enhanced Switch Expression:
public String getSeasonDescription(Season season) {
return switch (season) {
case SPRING -> "Flowers are blooming!";
case SUMMER -> "It's hot outside!";
case AUTUMN -> "Leaves are falling!";
case WINTER -> "Snow is coming!";
};
}
Pattern Matching For instanceof
Another design improvement has also affected the instanceof
operator. Now, instanceof
is safer and more concise. With this change, it is no longer necessary to first check if a given object is an instance of some class and then perform a cast; this can now be done in one line. As stated, this is not just syntactic sugar but rather a more optimized operator.
Java 11. Classic intanceof
:
public void findInstance(Object o) {
if (o instanceof String) {
String s = (String) o;
System.out.printf("Object is a string %s", s);
} else if (o instanceof Number) {
Number n = (Number) o;
System.out.printf("Object is a number %n", n);
}
}
Java 17. Updated intanceof
public void findInstance(Object o) {
if (o instanceof String s) {
System.out.printf("Object is a string %s", s);
} else if (o instanceof Number n) {
System.out.printf("Object is a number %n", n);
}
}
Sealed Classes
Java 17 has also taken security into account and made a significant step in that direction. The idea was to restrict the inheritance of a class or interface while keeping it public. As a result, new types of classes, sealed classes, were added to Java. The syntax of a sealed class allows you to specify descendants that can use its functionality. In turn, inheritors can also allow or deny inheritance or specify classes that can be inherited along the chain. This feature allows you to be more flexible in creating a project and conveniently adjust the API of your code.
Java 17. Sealed class:
public sealed class SealedClass permits AnotherSealedClass, AnotherNonSealedClass, AnotherFinalClass {
}
Java 17. Non-sealed inheritor:
public non-sealed class AnotherNonSealedClass extends SealedClass {
}
Java 17. Final inheritor:
public final class AnotherFinalClass extends SealedClass {
}
Java 17. Sealed inheritor:
public sealed class AnotherSealedClass extends SealedClass permits AnotherNonSealedClassTwo {
}
Java 17. Non-sealed inheritor level two:
public non-sealed class AnotherNonSealedClassTwo extends AnotherSealedClass {
}
Helpful NullPointerExceptions
And finally, an incredibly useful update in Java 17 is the improved NullPointerException! Finally, in the stack trace logs, you can see which specific field caused the NullPointerException. This feature alone should encourage you to switch to Java 17. You no longer need to poke around in the code for a long time in search of that sinister place where the exception occurred; now Java will do everything for you.
Java 11. NPE:
public static void main(String... args) {
String s = null;
System.out.println(s.toLowerCase());
}
Exception in thread "main" java.lang.NullPointerException
at Main.main(Main.java:4)
Java 17. Improved NPE:
public static void main(String... args){
String s = null;
System.out.println(s.toLowerCase());
}
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "String.toLowerCase()" because "s" is null
at edu.javamodules/edu.javaversions.eleventoseventeen.NpeExample.main(NpeExample.java:7)
Other innovations
Of course, this is not the whole list of changes that have been made in Java 17, but discussed innovations are the most noticeable ones. As always, Java developers have done an excellent job in improving the JVM, making it even more efficient.
Verdict
All the improvements made in Java 17 convey one message: it’s time to switch to this version. The transition promises a more concise syntax and improved performance. Your project will gain security, flexibility, and better error messages. If you have already migrated to Java 11, then moving to Java 17 will be smooth. Java’s competitive advantage shines here as backward compatibility allows you to switch to Java 17 without any code changes and take advantage of all the updated features. Version 17 is a Long-term Support version, ensuring you receive all the necessary security updates for an extended period.
By: Sergei Dzeboev
Originally published at Hackernoon
Source: cyberpogo.com
For enquiries, product placements, sponsorships, and collaborations, connect with us at [email protected]. We'd love to hear from you!
Our humans need coffee too! Your support is highly appreciated, thank you!