laitimes

Exciting new features from Java 12 to Java 17

Author | Christopher Bielak

Translated by | Tu Ling

Planned by | Ding Xiaoyun

In September 2021, Oracle released Java 17, the next long-term support release for Java. If you're using Java 8 or Java 11, you probably won't notice some cool new features added after Java 12.

Because this is an important release, I'll highlight some new features that I'm personally interested in!

It's important to note that most changes in Java first need to go through the "preview" phase, which means they are added to a version but are not yet complete. One can try to use them, but it is not recommended to use them in a production environment.

All of the features listed here have been officially added to Java and have passed the preview phase.

1: Seal class

A seal class that is in preview in Java 15 and has become a formal feature in Java 17 provides a new approach to inheritance rule qualification. When you add the sealed keyword in front of a class or interface, you also add a manifest of classes that allow you to extend the class or implement the interface. For example, if you define a class:

That is, only Red, Blue, and Yellow can inherit this class, and no other class can compile if they want to inherit it.

You can also leave the permits keyword instead of using and then put the class definition in the same file as the class, as follows:

Note that these subclasses are not nested in the sealed class, but are placed after the class definition. This has the same effect as using the keyword permit, which extends color to only Red, Blue, and Yellow.

So, where are seal classes usually used? By qualifying inheritance rules, it also qualifies encapsulation rules. Suppose you are developing a library and need to include the abstract class Color in it. You know the Color class and which classes need to extend it, but if it's declared public, is there anything you can do to stop external code from extending it?

What if someone misunderstands what it's for and extends it with Square? Is this in line with your intentions? Or do you actually want Color to remain private? But even then, package-level visibility doesn't avoid all problems. What if someone later extended the library? How can they know that you only intend to have a small subset of classes integrated with Color?

A seal class not only protects your code from external code, but is also a way to communicate intent to someone you may have never met. If a class is sealed, you are communicating that only certain classes can extend it. This robustness ensures that anyone who reads your code years from now will understand the rigor of the code.

2: Enhanced null pointer exception

The enhanced null pointer exception is an interesting update – not too complicated, but still popular. This enhancement, generally available in Java 14, improves the readability of NullPointerException (NPE) and prints the names of methods called and empty variables where the exception is thrown. For example, if you call a.b.getName() and b is empty, the stack trace for the exception tells you that the call to getName() failed because b is empty.

We all know that NPE is a very common exception, and while it's not hard to figure out the root cause of the thrown exception in most cases, you'll come across situations where you have two or three suspicious variables at the same time from time to time. You go into debug mode and start looking at the code, but the problem is difficult to reproduce. You can only try to recall what you did initially that led to the throwing of npe.

If you can get this information in advance, you don't have to debug it with all this hassle. This is the shining point of this feature: no more guessing where npE was thrown. At critical moments, when you encounter unusual scenarios that are difficult to reproduce, you have everything you need to solve the problem.

It was an absolute savior!

3: Switch expression

I hope you'll be patient with me — the switch expression (previewed in Java 12 and officially added to Java 14) is some combination of a switch statement and a lambda. Really, when I first described a switch expression to someone, my statement was that they lambdaized the switch statement. Consider the following syntax:

Now you see what I mean?

One obvious difference is that there is no break statement. Switch expressions continue Oracle's trend to make Java syntax more concise. Oracle hates that most switch statements contain a lot of CASE BREAK, CASE BREAK, CASE BREAK, etc.

Honestly, they're right to hate this because it's easy for people to make mistakes in this place. Do any of us dare to say that they have never encountered this situation: forget to add a break statement to the switch, only if the code crashes at runtime? The switch expression fixes this in a fun way, you just need to separate all the values in the same code block with commas. That's right, you don't need to use break anymore! It will take care of it for you!

The switch expression also adds the yield keyword. If a case enters a code block, yield is returned as a switch expression. For example, if we modify the above code slightly:

Overall, the switch expression is a more concise switch statement, but it does not replace the switch statement, both of which are available.

4: Text block

The Text Block feature, previewed in Java 13 and officially added to Java 15, simplifies writing multiline strings, supports line breaks, and maintains indentation without the need for escape characters. To create a block of text, all you need is this:

Note that this variable is still a string, but it implies newline and tab characters. Similarly, if we want to use quotation marks, we don't need to escape the characters:

The only place you need to use a backslash escape character is when you want to include """" in the text block:

In addition to this, you can call String's format() method to replace placeholders in the text block with dynamic content:

Spaces after each line are cut out unless you specify '\s', which is an escape character for the text block:

So, in what cases would a block of text be used? In addition to being able to format large blocks of text, it becomes very easy to paste code snippets into strings. Because indentation is preserved, if you're going to write an HTML or Python code block, or any other language, you can write them the normal way you would and enclose them with "", and you can preserve the formatting of the code. You can even write JSON in blocks of text and easily insert values using the format() method.

Overall, this is a very convenient feature. While text blocks may seem like a small feature, in the long run, small features like this one that can improve development efficiency will gradually increase.

5: Record class

The record class, previewed in Java 14 and officially added to Java 16, is a data class that handles all boilerplate code related to POJO. That is, if you declare a record class:

The equals() and hashcode() methods are implemented automatically, and toString() will return the values of all the fields contained in this class instance, and most importantly, x() and y() will return the values of x and y, respectively. Think about the POJO classes you wrote about earlier, and imagine replacing them with the record class. Isn't it much better? How much has been saved?

In addition to this, the record class is final and immutable — it cannot be inherited, and once a class instance is created, its fields cannot be modified. You can declare methods in the record class, including non-static methods and static methods:

The record class can have multiple constructors:

It is important to note that when you declare a custom constructor in the record class, you must call the default constructor. Otherwise, the record class will not know what to do with its value. If you declare a constructor that is the same as the default constructor, you initialize all the fields:

There are many topics to discuss about the record class. This is a big change, and they can be very useful when used where appropriate. I'm not covering everything here, but hopefully this gives you an idea of the capabilities they have to offer.

6: Pattern matching

Pattern matching is another step Oracle has taken in its fight against Java's lengthy syntax. Pattern matching was previewed in Java 14 and Java 15 and officially added to Java 16 to eliminate unnecessary type conversions after the instanceof condition is met. For example, we are all familiar with code like this:

If you want to access Car's methods, you have to do so. In the second line, o is an instance of Car, which is beyond doubt, and instanceof has confirmed this. If we use pattern matching, just make a small change:

All object type conversions are now done by the compiler. It may seem like a small change, but it avoids a lot of boilerplate code. This also applies to conditional branches when you enter a branch that already specifies the object type:

You can even use pattern matching on the instanceof line:

While pattern matching is not as big as some of the other changes, it simplifies commonly used code.

Java 17 will continue to evolve

Of course, Java 12 to Java 17 isn't just about these updates, these are just the parts that I think are interesting. Running a large project with the latest Java version takes a lot of courage, and even more so if you're migrating from Java 8.

If someone hesitates, it's understandable. But even if you don't have a migration plan, or if an upgrade plan can last for years, it's always good to keep up with the new features of the language. I hope that the content I share will make it more intrusive so that anyone who has read it can start thinking about how to use it!

Java 17 is special – it's the next long-term support release, taking over the baton of Java 11 and likely to be the most migrated version of Java in the coming years. Even if you're not ready for it now, you can start learning, and you're already an experienced developer when you're in a Java 17-based project!

About the Author:

Christopher Bielak is a Java developer at Saggezza, a company acquired by Infostretch, and he has a keen interest in software development languages. He has 10 years of experience in banking and finance, advocating for a move towards more cutting-edge technologies.

https://www.infoq.com/articles/six-features-jdk12-to-jdk17/

Read on