Jdk17 new features and future development trends

Recently, many people are saying that SpringBoot is going to release version 3.0, and announced that it will no longer support Java 8, and the minimum requirement is Java 17.

In fact, as early as September 2021, when the news about Spring Framework 6.0 came out, Spring officially made it clear that it would not be backward compatible, and the minimum JDK version was JDK 17.

insert image description here

In 2022, Spring Framework 6.0 and SpringBoot 3.0 will be launched. Before that, the Java community was very strong, and it has always been "you can post the new version, I use Java 8". No matter how the new version is released, few people are willing to upgrade.

This time, Spring directly made a big move, skipping JDK 8-16, and directly upgrading to JDK 17. I don’t know how it will affect the Java ecosystem.

Why Java 17

With so many new versions of JDK, and JDK 18 and JDK 19 will be launched in 2022, why did Spring choose JDK 17?

The main reason is that it is an LTS version. The so-called LTS is Long Term Support, that is, the version that is officially guaranteed to be supported for a long time.

From the birth of JDK to the present, the long-term supported versions mainly include JDK 7, JDK 8, JDK 11 and JDK 17

69dc43bcecc1fee4194615f381f5782d.png

This time Spring directly skipped JDK 11 and upgraded to JDK 17. The main consideration should be that JDK 17 has more new feature support.

Next, we introduce several new features, which are closely related to our developers, or will affect our writing code.

New features supported by JDK 17

The so-called new features here are not just new features in JDK 17, but new features in JDK 17 compared with JDK 8.

local variable type inference

In versions prior to Java 10, we wanted to define when defining local variables. We need to provide the explicit type on the left side of the assignment and the implementation type on the right side of the assignment:

MyObject value = new MyObject();

In Java 10, the function of local variable type inference is provided, and variables can be declared through var:

var value = new MyObject();

Local variable type inference will introduce the "var" keyword without explicitly specifying the variable's type.

In fact, the so-called local variable type inference is also a syntactic sugar provided by Java 10 to developers.

Although we use var to define in the code, the virtual machine does not know this var. During the process of compiling the java file into a class file, it will desugar and use the real type of the variable to replace var (for details, please refer to: I decompiled the local variable type inference of Java 10)

switch expression

Switch expressions were introduced in JDK 12 as a preview feature. And this feature was modified in Java 13, and the yield statement was introduced for returning values.

In the subsequent Java 14, this function is officially provided as a standard function.

In the past, it was quite troublesome for us to return content in the switch. The general syntax is as follows:

int i;switch (x) {case "1":i=1;break;case "2":i=2;break;default:i = x.length();break;}

In JDK13 use the following syntax:

int i = switch (x) {case "1" -> 1;case "2" -> 2;default -> {int len = args[1].length();yield len;}};

or

int i = switch (x) {case "1": yield 1;case "2": yield 2;default: {int len = args[1].length();yield len;}};

After that, there is an additional keyword in the switch to jump out of the switch block, that is yield, which is used to return a value.

The difference with return is: return will directly jump out of the current loop or method, while yield will only jump out of the current switch block.

Text Blocks

There is a Text Blocks preview feature in Java 13 and a preview of a second version in Java 14.

A text block, a text block, is a multiline string literal that avoids the need for most escape sequences, automatically formats strings in a predictable manner, and gives the developer control over the formatting if needed.

We used to copy a text string from the outside to Java, and it will be automatically escaped, such as the following string:

<html><body><p>Hello, world</p></body></html>

Copying it into a Java string would display the following:

"<html>\n" +"    <body>\n" +"        <p>Hello, world</p>\n" +"    </body>\n" +"</html>\n";

That is, it is automatically escaped. Such a string does not look very intuitive. In JDK 13, the following syntax can be used:

"""<html><body><p>Hello, world</p></body></html>""";

Use """ as the start and end of the text block, in which you can place multi-line strings without any escaping. It looks very refreshing.

Such as common SQL statements:

String query = """SELECT `EMP_ID`, `LAST_NAME` FROM `EMPLOYEE_TB`WHERE `CITY` = 'INDIANAPOLIS'ORDER BY `EMP_ID`, `LAST_NAME`;""";

It looks more intuitive and refreshing.

Records

A new feature is included in Java 14: EP 359: Records,

The goal of Records is to extend the Java language syntax. Records provides a compact syntax for declaring classes, used to create a class that is "fields, just fields, nothing but fields".

By making such a declaration on the class, the compiler can automatically create all methods and make all fields participate in methods such as hashCode(). This is a preview feature in JDK 14.

A record can be defined using the record keyword:

record Person (String firstName, String lastName) {}

record solves a common problem with using classes as data wrappers. Pure data classes are dramatically simplified from a few lines of code to one line of code. (For details, see: Java 14 is released, can you define classes without using "class"? And you will kill Lombok!)

closed class

Before Java 15, Java believed that "code reuse" was always an ultimate goal, so a class and interface could be implemented or inherited by any class.

However, in many scenarios, doing so is prone to errors and does not conform to the real laws of the physical world.

For example, suppose a business domain applies only to cars and trucks, but not to motorcycles.

When creating the Vehicle abstract class in Java, only the Car and Truck classes should be allowed to extend it.

In this way, we want to ensure that there is no misuse of the Vehicle abstract class within the domain.

To solve a similar problem, a new feature was introduced in Java 15 - containment.

To define a sealed interface, apply the sealed modifier to the interface declaration. Then, the permit clause specifies the classes that are allowed to implement the sealed interface:

public sealed interface Service permits Car, Truck {}

The above code defines a closed interface Service, which stipulates that it can only be implemented by two classes, Car and Truck.

Similar to interfaces, we can define sealed classes by using the same sealed modifier:

public abstract sealed class Vehicle permits Car, Truck {}

Through the airtight feature, the Vehicle class we defined can only be inherited by Car and Truck.

instanceof pattern matching

instanceof is a keyword in Java. We will use instanceof to make a judgment before we cast the type, for example:

if (animal instanceof Cat) {Cat cat = (Cat) animal;cat.miaow();} else if (animal instanceof Dog) {Dog dog = (Dog) animal;dog.bark();}

Java 14 brings an improved version of the instanceof operator, which means we can write the previous code example in a more concise way:

if (animal instanceof Cat cat) {cat.miaow();} else if(animal instanceof Dog dog) {dog.bark();}

It is not difficult for us to find that this way of writing greatly simplifies the code, omits the process of explicit mandatory type conversion, and greatly improves the readability.

switch pattern matching

Based on the feature of instanceof pattern matching, we can use the following methods to process object o:

static String formatter(Object o) {String formatted = "unknown";if (o instanceof Integer i) {formatted = String.format("int %d", i);} else if (o instanceof Long l) {formatted = String.format("long %d", l);} else if (o instanceof Double d) {formatted = String.format("double %f", d);} else if (o instanceof String s) {formatted = String.format("String %s", s);}return formatted;}

It can be seen that a lot of if-else is used here. In fact, Java provides us with a multi-way comparison tool, that is switch, and since Java 14, switch expressions are supported, but the function of switch has always been very limited.

In Java 17, Java engineers extended the switch statement and expression to be applicable to any type, and allowed not only variables in case labels, but also pattern matching. We can then rewrite the above code more clearly and reliably, for example:

static String formatterPatternSwitch(Object o) {return switch (o) {case Integer i -> String.format("int %d", i);case Long l    -> String.format("long %d", l);case Double d  -> String.format("double %f", d);case String s  -> String.format("String %s", s);default        -> o.toString();};}

It can be seen that the above switch processes an Object type, and the case is no longer an exact value match, but a pattern match.

Summarize

Above, we have introduced several new features from JDK 9 to JDK 17 that can change the way we write code. In fact, among the many versions, there are some other features and optimizations, which we have not expanded here one by one.

If you are interested, you can go to the JDK official website to view the introduction of new features of each version.

With the introduction of Spring Framework 6 and SpringBoot 3.0, it is believed that some companies will adopt the new version in new projects, so JDK 17 is bound to be applied to the production environment.

Most of the above features are friendly to development and can be applied if there is a chance.

Guess you like

Origin blog.csdn.net/qq_42672856/article/details/131271017