JDK 16 was officially released yesterday, and early adopters of new features are coming!

JDK 16 has completed the final candidate version on February 18, 2021, and will be officially released on March 16, 2021. Like JDK 15, JDK 16 will also be a short-term version, only supporting six months. The JDK 17 scheduled to be released in September 2021 will be a long-term support (LTS) version and will be supported for several years. Although JDK 16 is a short-term version, and most companies or projects are still stuck on JDK 11 released in September 2018 (or even JDK 8 released earlier in March 2014), it does not prevent Javaer from making new versions of JDK. Expectation and passion for continuous learning.

This article will play with you JDK 16.

List of new features


Before we start, let's take a look at the 17 new features brought by the JDK 16 version.

▐New   features to be interpreted in this article

357: OpenJDK source code repository migrated from Mercurial to Git. Efforts to promote this change will show advantages in terms of the size of the version control system metadata, available tools, and hosting.

 

369: Migrate to GitHub. This change is based on the migration of the OpenJDK source code repository to Git. The JDK 16 source code repository will appear on the most popular social networking sites for programmers.

 

386: On x64 and AArch64 architectures, port JDK to Alpine Linux and other Linux distributions that use musl as their main C library. Musl is a Linux implementation of the standard library functions described in the ISO C and Posix standards. Alpine Linux is widely used in cloud deployment, microservices, and container environments due to its small image size. The Linux version of the Docker container image is less than 6MB. Let Java run out of the box in such settings and allow Tomcat, Jetty, Spring, and other popular frameworks to work in these environments. By using jlink to reduce the size of the Java runtime, users can create a smaller image to run specific applications.

 

394: The pattern matching of the instanceof operator has been previewed in JDK 14 and JDK 15, and will be finalized in JDK 16. Pattern matching enables the general logic in the program (that is, the conditional extraction of components from the object) can be expressed more concisely and safely.

 

395: Provide Record type as a transparent carrier of immutable data.

▐Other   new features

347: Enable C++ 14 language features, allow C++ 14 features to be used in JDK C++ source code, and provide specific guidance on which features can be used in HotSpot code.

 

376: Move ZGC (Scalable Low Latency Garbage Collector) thread stack processing from a safe point to the concurrent phase. The ZGC garbage collector is designed to make GC pauses and scalability issues in HotSpot a thing of the past.

 

380: Add Unix-Domain Socket Channels, where Unix-Domain (AF_UNIX) socket support is added to the Socket Channel and Server Socket Channel APIs in the nio.channels package.

 

387: The flexible Metaspace function can return the memory occupied by the Class Metadata (Metaspace) of the unused HotSpot virtual machine to the operating system more quickly, thereby reducing the occupancy of Metaspace and simplifying the code of Metaspace to reduce maintenance costs.

 

388: Port JDK to Windows/AArch64 platform.

 

389: The external linker API in the incubation stage supports static type pure Java access to native code. The purpose of this plan is to replace JNI (Java Native Interface) with a more advanced pure Java development model to provide interaction with the C language. Its performance will be more superior than JNI.

 

390: Warning recommendation for value-based classes: Specify the original packaging class as a value-based class, deprecate its constructor for removal, and prompt a new deprecation warning. In the Java platform, any incorrect attempts to synchronize instances of value-based classes will be warned.

 

392: Provide jpackage tool for packaging independent Java applications.

 

396: By default, the internal structure of the JDK is strongly encapsulated, except for key internal APIs (such as misc.Unsafe). The goals of this plan include improving the security and maintainability of the JDK, and encouraging developers to gradually migrate from directly using internal elements to using standard APIs, so that both developers and end users can easily upgrade to future versions of Java.

 

397: It was previewed in JDK 15 before. The sealed classes and interfaces in the second preview in JDK 16 limit the classes and interfaces that can be extended or implemented. The goals of this plan include allowing the creator of a class or interface to control the code responsible for implementing it, providing a more declarative way than access modifiers to limit the use of superclasses, and supporting the future development of pattern matching by providing a basis for pattern analysis.

 

338: Vector API in the incubation phase (JDK will be equipped with an incubator module), jdk.incubator.vector, to express vector calculations compiled into the best hardware instructions on the supported CPU architecture to achieve better than equivalent scalar calculations performance.

 

393: The external memory access API in the incubation stage allows Java programs to safely access external memory outside the Java heap (including local, persistent media, and managed heap memory).

 

The new feature is numbered as the identifier of the JDK Enhancement Process before the new feature. For details, see References

Try it now


After browsing the 17 new features, I can’t wait to try JDK 16, and some of the features that are helpful to engineering.

Then download the JDK 16 candidate version through the JDK official website (http://jdk.java.net/16/).

 

To easily switch between multiple JDK versions in the system, you can use jenv (https://github.com/jenv/jenv).

We add the downloaded JDK16 path to jenv, and you can use it after doing the following settings.

jenv add ${JDK16_Path}
jenv global openjdk64-16

If all goes well, when you check the JDK version, there will be a return similar to the following information.

java -version
openjdk version "16"2021-03-16
OpenJDK Runtime Environment (build 16+36-2231)
OpenJDK 64-Bit Server VM (build 16+36-2231, mixed mode, sharing)

If you are using an earlier version of IDEA as a development tool, you may receive the following errors when running the program using JDK 16:

Cannot determine path to 'tools.jar' library for 16 (path/to/jdk-16) when running from IDEA, you should update to the latest version.

This is because JDK9 has refactored the Java runtime, and has deleted rt.jar, tools.jar, dt.jar and various other internal JAR packages. However, earlier development tools usually depend on this type of JAR package, which can be solved by upgrading IDEA.

Go to the official website to get a pre-release version of IDEA 2021.1 EAP

(Https://www.jetbrains.com/zh-cn/idea/nextversion/) to experience in advance (you can also wait for the official version of 2021.3).

Interpretation of new features


▐Migrate   to GitHub

As early as September 2020, OpenJDK has used the jdk repository on Github as the main read/write repository for JDK 16 source code. With the official release of JDK 16, this will be the first JDK version developed by OpenJDK on Github.

 

The three main reasons that prompted the migration of the OpenJDK source code repository from Mercurial to Git: version control system metadata, available tools, and available hosting size.

  • In terms of version control metadata size, the initial prototype of the converted repository has shown a significant reduction in the size of version control metadata. For example, the .git directory of the jdk repository using Git is approximately 300MB, while the .hg directory using Mercurial is approximately 1.2GB. Reducing metadata preserves local disk space and reduces cloning time, while reducing the data transferred.

  • In terms of available tools, Git has more tools than Mercurial. All text editors can implement Git integration locally or through plugins. In addition, almost all IDEs have Git integration, including Eclipse, Visual Studio, and IDEA.

  • In terms of available hosting, there are many options for hosting Git repositories, whether self-hosted or hosted as a service. Reasons for using external source code hosting providers include performance, access control for Web APIs that interact with developers, and a thriving community.

After the migration of OpenJDK to Github, there are still many conveniences for Java developers:

  • By forking a JDK 16 source code repository (https://github.com/openjdk/jdk), you can read the source code while taking notes and submit it to facilitate continuous learning of the JDK source code. Use Git's upsteam to keep the JDK source code updated while also keeping itself updated.

  • If the internet speed is fast enough, use Github1s (https://github.com/conwnet/github1s), a tool for reading code online on Github, and quickly browse the JDK 16 source code in the browser (https://github1s.com/openjdk/jdk/ releases/tag/jdk-16%2B35) is also very convenient.

If you are working and studying under IDEA, clone the JDK 16 source code,

Open Project Structure (command+;), set the Project SDK to JDK 16, and set the Project language level to 16.

After that, you can look at the JDK 16 source code happily.


  Porting JDK to Alpine Linux

In the cloud-native era, personal understanding to improve efficiency is the first principle:

  • Smaller mirror volume will be faster when distributing

  • Application/container startup needs to be fast

This will ensure that the system scales quickly enough, and rollbacks are handled quickly when problems occur.

In addition, for cost reduction considerations, a smaller image volume will occupy less memory and consume less resources during distribution.

 

Alpine Linux is an independent non-commercial general-purpose Linux distribution that fits the principle of cloud-native efficiency improvement.

It focuses on security, simplicity and resource efficiency, and is built around musl libc and busybox. This makes it smaller than traditional GNU/Linux distributions.

After the JDK is ported to Alpine Linux, it will allow Tomcat, Jetty, Spring and other popular frameworks to work in it. Users can create a smaller image to start and run specific applications.

 

Prepare Docker in advance, we first build an Alpine Linux image, then add JDK 16, and finally run a simple Spring Boot program to demonstrate.

▐Build   Alpine Linux image

# 获取Alpine Linux镜像
docker pull alpine
# 运行镜像
docker run alpine echo'Hello Alpine!'

Checking the image size through the docker images command will find that at the time of the completion of this article, the image size of alpine is only 5.6MB. Compared to debian, ubuntu, centos and other systems that move dozens or even hundreds of MB of mirrors, alpine is really small!

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
alpine              latest              7731472c3f2a        7 weeks ago         5.61MB

▐Add JDK 16  

OpenJDK uses jlink (JEP 282: https://openjdk.java.net/jeps/282) to reduce the size of the Java runtime. We can get the image from DockerHub:

16-jdk-alpine(https://hub.docker.com/_/openjdk?tab=tags&page=1&name=16-jdk-alpine&ordering=last_updated)。

Or the following Docker command:

docker pull openjdk:16-jdk-alpine

▐Run Spring Boot  

First prepare a Spring Boot FatJar program, you can get Hello World from the Spring Boot official website! Sample program (https://spring.io/guides/gs/rest-service/).

Create a Dockerfile, use openjdk:16-jdk-alpine, and add the Spring Boot program.

FROM openjdk:16-jdk-alpine
VOLUME /tmp
ARG JAR_FILE
ADD ${JAR_FILE} app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]

▐Build and run  

# 构建镜像,设置JAR_FILE参数指向Spring Boot程序Jar包路径
docker build --build-argJAR_FILE=target/rest-service-0.0.1-SNAPSHOT.jar -t alpine-jdk16-app:latest .
 
# 查看镜像
docker images
 
# 根据镜像,启动容器运行
# -d参数 后台运行
# -p参数 Spring Boot默认端口8080,映射到容器端口8080
docker run -d-p8080:8080 alpine-jdk16-app:latest
 
# 查看容器运行
docker ps
 
# 验证成功之后可以停止容器
docker stop${CONTAINER_ID}
 
# 访问应用
curl-w'\n' http://127.0.0.1:8080/greeting?name=jdk16

At this point, Spring Boot with JDK 16 runtime through the Alpine Linux system has been started and can be accessed normally.

The size of the JDK 16 image of the Alpine system is about 321MB. Compared with the 467MB of Oracle's official Linux version image, a 30%+ reduction.

Record class


Starting from JDK 14, a preview feature of the Record record class has been provided, and this feature will become a permanent feature of JDK 16. The Record class is a transparent carrier of immutable data in response to complaints about Java being too verbose and formal. The goals of this plan include designing an object-oriented constructor that represents a collection of simple values, helping developers focus on modeling immutable data rather than extending behavior, and automatically implementing data-driven methods (such as equals() and attribute access)器).

 

This type can be created by the newer version of IDEA:

After the Record record class is declared, there is almost no need to add additional code. A set of implicit declarations makes the code very concise:

  • Implicitly declared properties

  • Implicitly declared constructor

  • Implicitly declared equals(), hashCode(), toString()

  • The accessor of the attribute is implicitly declared, and the name of the accessor is the same as that of the attribute

public record Point(int x, int y) {}

The Record record class supports the Local Classes feature, so when you need to temporarily use the Record, it can be very convenient to define and use:

List<Merchant>findTopMerchants(List<Merchant> merchants, int month) {
    // Local record
    record MerchantSales(Merchant merchant, double sales) {}
 
    // 使用MerchantSales Record类临时包装merchant和sales,方便做处理。
    return merchants.stream()
        .map(merchant ->new MerchantSales(merchant, computeSales(merchant, month)))
        .sorted((m1, m2) ->Double.compare(m2.sales(), m1.sales()))
        .map(MerchantSales::merchant)
        .collect(toList());
}

The Record record class can replace the tuple function provided by the tool libraries outside the JDK, such as Tuple, Pair, and the pattern matching feature described below, can make the code very concise.

▐Pattern matching  


Beginning with JDK 14, a preview feature of pattern matching has been introduced, and this feature will also become a permanent feature of JDK 16. Therefore, although JDK 16 is a short-term version, it does not prevent us from continuing to use the pattern matching feature in future JDK versions.

 

The current stage of pattern matching is limited to one pattern (type pattern) and one language construct (instanceof), but this is only part of the complete feature. Even so, we have already obtained a significant benefit: the redundant coercion disappears, the redundant code is eliminated, the more important code gets a clearer attention, and the hidden bugs are eliminated.

 

for example:

When we need to parse objects in development, we will use methods similar to the following

if (obj instanceofString) {
    String s = (String) obj;
    ...
}

Use the equivalent code after pattern matching:

if (obj instanceofString s) {
    // 通过使用模式匹配可以直接使用s局部变量
    ...
}

Does the code look much cleaner?

Using instanceof to obtain the object type is a form of conditional extraction. After the object type is obtained, the object is always cast to that type.

In the past, explicit type conversion must be performed after instanceof. This is a tedious operation. The benefits of combining these operations are not only for brevity, but also eliminate a common source of error: cutting and pasting instanceof and coercion Code, it is easy to forget to modify the cast type after modifying the type of instanceof, which gives a hiding place for loopholes. Through the pattern matching of instanceof to eliminate this problem, we can also eliminate all this type of bug.

 

Another place where you often need to do this kind of "check first and then force conversion" is the equals method.

Let's look at another example:

publicbooleanequals(Object o) {
    if (!(o instanceof Point))
        returnfalse;
    Point other = (Point) o;
    return x == other.x && y == other.y;
}

Use the equivalent code after pattern matching:

publicbooleanequals(Object o) {
    return (o instanceof Point other)
        && x == other.x && y == other.y;
}

This code has the same effect, but is simpler and more straightforward, because we can only use a compound Boolean expression to express an equivalent condition instead of using a control flow statement.

 

Pattern-matched bind variables (as in the above code example obj instanceof String s is a bind variable) except for the special declaration position, its scope is also different from "normal" local variables.

For example, we can write:

if (a instanceof Point p) {
    // p is in scope
    ...
} else {
    // p not in scope here
}
 
// p not in scope here
 
if (b instanceof Point p) {     // Sure!
        ...
}

This special scope allows us to freely redeclare bind variables in the case of if-else multi-branch, and it is also convenient to consider the case in switch in the future. Such as:

if (x instanceofInteger num) { ... }
elseif (x instanceofLong num) { ... }
elseif (x instanceofDouble num) { ... }

If pattern matching can eliminate 99% of cast operations in Java code, then it will definitely be popular. But it is not limited to this. Over time, other types of patterns will appear, which can perform more complex condition extraction, use more complex ways to combine patterns, and provide other constructs that can use patterns: such as switch, Even catch, coupled with the currently permanently supported Record class and the sealed class in the preview and other related features, pattern matching will definitely be able to greatly simplify the code we write in the future.

end


This article extracts several features that are more helpful for engineering work and learning from the 17 new features brought by the JDK 16 version, and quickly understands these features.

 

Most companies or projects are still using JDK 8 (it still occupies 80% of the JDK market and is absolutely mainstream), which is derived from the ultra-luxury new features of JDK 8, such as functional interfaces, lambda expressions, method references/constructors References, stronger Steam API, interface enhancements, Optional, Metaspace in JVM instead of PermGen space, etc.

 

We can also see that in order to keep up with the fast pace of current technological changes, Java continues to introduce new ones.

Starting from JDK 9, the release of the Java version has been changed to once every 6 months. JDK 11 is the long-term support version and JDK 17 to be released in the second half of the year.

There are also some important new features in JDK 9~JDK15, such as

  • JDK 9 module system, JShell interactive command line

  • JDK 10 local variable type inference

  • JDK 11 ZGC trial, HTTP Client API, Steam and other enhancements

  • JDK 12 switch expression extension, adding a set of micro-benchmark suite based on JMH

  • JDK 13 Socket API refactoring, text block (multi-line text)

  • JDK 14 more valuable NPE error messages, partial preview of JDK 16 features

  • Preview of JDK 16 features such as JDK 15 sealed class and Record class

I hope this rapid version iteration strategy can keep Java alive and enable developers to use it more efficiently and robustly!

Reference


  • JDK 16 status, release schedule and new features

    (http://openjdk.java.net/projects/jdk/16/)

  • JDK 16: The new features in Java 16

    (https://www.infoworld.com/article/3569150/jdk-16-the-new-features-in-java-16.html)

  • Java source code repository migrated to Github

    (https://www.infoworld.com/article/3569068/javas-move-to-github-set-for-september.html)

  • Run Spring Boot in Alpine + OpenJDK image

    (https://blogs.oracle.com/developers/running-spring-boot-in-a-docker-container-on-openjdk,-oracle-jdk,-zulu-on-alpine-linux,-oracle-linux,-ubuntu)

  • JEP 394: Pattern Matching for instanceof

    (https://openjdk.java.net/jeps/394)

  • JEP 395: Records

    (https://openjdk.java.net/jeps/395)

  • JEP 397: Sealed Classes (Second Preview)

    (https://openjdk.java.net/jeps/397)


  join us 

Welcome to join the Tao Department architecture team. The team members gather here, including the founders of Alibaba Mobile Middleware, the core members of Dubbo, and a group of small partners who love technology and hope to use technology to promote business.

 

The Tao Department architecture team promotes the upgrade of the Tao Department (Taobao, Tmall, etc.) architecture, and is committed to providing the Tao Department and the entire group with basic core capabilities, products and solutions:

  • Business high-availability solutions and core capabilities (refined traffic control Marconi platform: Provides flexible high-availability solutions for business with adaptive flow control, isolation and fusing, high site availability: fault self-healing, multiple computer rooms and remote disaster recovery and Quick cut flow recovery

  • A new generation of business research and development model FaaS (one-stop function research and development Gaia platform)

  • Implementation and landing of the next generation network protocol QUIC

  • Mobile middleware (API gateway MTop, access layer AServer, message/push, configuration center, etc.)

Looking forward to participating in the construction of the basic platform of Tao Department together~

 

Send your resume to???: Zebin [email protected]

(Tao Department Architecture-Application Architecture Leader)

✿Extended   reading

Author | Xiong Zheng (Eight Winds)  

Edit| Orange

Produced| Alibaba's new retail technology

Guess you like

Origin blog.csdn.net/Taobaojishu/article/details/114957783