This is the second day of my participation in the November Gwen Challenge. Check out the details: the last Gwen Challenge 2021

Like and see, unlimited power. Wechat search “program ape Alang”.

This article Github.com/niumoo/Java… And unread code blog has been covered, with lots of knowledge points and a series of articles.

Java 17 is a long Term Support (LTS) release with 14 new features released on September 14, 2021.

OpenJDK Java 17 download: jdk.java.net/archive/

Its Java documentation: 17 openjdk.java.net/projects/jd…

JEP describe
JEP 306 Restore always strict floating-point semantics
JEP 356 Enhanced pseudo-random number generator
JEP 382 Use the new macOS rendering library
JEP 391 Supports macOS/AArch64 architecture
JEP 398 Example Delete the enabled Applet API
JEP 403 Stronger encapsulation inside the JDK
JEP 406 Switch Mode matching (preview)
JEP 407 Remove the RMI Activation
JEP 409 Sealed Classes
JEP 410 JEP 401: Removed experimental AOT and JIT compilers
JEP 411 By the Security Manager
JEP 412 External functions and memory apis (incubator)
JEP 414 Vector API (Second Incubator)
JEP 415 Specifies the deserialization filter for the context

This article is part of a series of tutorials on new Features in Java that cover the new features of each version of Java.

1. JEP 306: Restore always strict floating point semantics

Since we are restoring strict floating-point semantics, we are always strict floating-point semantics until a certain point in time. Prior to Java SE 1.2, all floating-point calculations were strictly implemented. However, overly strict floating-point calculations running on the popular x86 architecture and X87 floating-point protocol processors required a lot of extra instruction overhead, so starting with Java SE 1.2, Strictfp (Strict float Point) keyword must be manually used to enable strict floating-point calculation.

But now, in 2021, the hardware has changed so much that the original problem no longer exists, so starting with Java 17, the always strict floating-point semantics feature has been restored.

Strictfp extension: StrictFP is a Java keyword that most people may not have noticed. It can be used on classes, interfaces, or methods. Floats and double expressions in strictFP-qualified parts perform strict floating-point calculations.

Here is an example where testStrictfp() is qualified by StrictFP.

package com.wdbyte;

public class Main {
    public static void main(String[] args) {
        testStrictfp();
    }

    public strictfp static void testStrictfp(a) {
        float aFloat = 0.6666666666666666666 f;
        double aDouble = 0.88888888888888888 d;
        double sum = aFloat + aDouble;
        System.out.println("sum: "+ sum); }}Copy the code

2. JEP 356: Enhanced pseudo-random number generator

Added new interface types and implementations for RPNG (Pseudorandom Number Generator), making it much easier to use various PRNG algorithms in code.

The RandomGenerator interface was added this time to provide a unified API for all PRNG algorithms and to obtain streams of different types of PRNG objects. A new class RandomGeneratorFactory is also provided to construct various Instances of RandomGenerator. Use serviceloader. provider in RandomGeneratorFactory to load various PRNG implementations.

Here is a usage example: Randomly select a PRNG algorithm to generate 5 random numbers within 10.

package com.wdbyte.java17;

import java.util.Date;
import java.util.random.RandomGenerator;
import java.util.random.RandomGeneratorFactory;
import java.util.stream.Stream;

/ * * *@author niulang
 */
public class JEP356 {

    public static void main(String[] args) {
        RandomGeneratorFactory<RandomGenerator> l128X256MixRandom = RandomGeneratorFactory.of("L128X256MixRandom");
        // Use a timestamp as a seed for random numbers
        RandomGenerator randomGenerator = l128X256MixRandom.create(System.currentTimeMillis());
        for (int i = 0; i < 5; i++) {
            System.out.println(randomGenerator.nextInt(10)); }}}Copy the code

Get the output:

7, 3, 4, 4, 6Copy the code

You can also iterate through all the PRNG algorithms.

RandomGeneratorFactory.all().forEach(factory -> {
    System.out.println(factory.group() + ":" + factory.name());
});
Copy the code

Get the output:

LXM:L32X64MixRandom
LXM:L128X128MixRandom
LXM:L64X128MixRandom
Legacy:SecureRandom
LXM:L128X1024MixRandom
LXM:L64X128StarStarRandom
Xoshiro:Xoshiro256PlusPlus
LXM:L64X256MixRandom
Legacy:Random
Xoroshiro:Xoroshiro128PlusPlus
LXM:L128X256MixRandom
Legacy:SplittableRandom
LXM:L64X1024MixRandom
Copy the code

You can see Legacy:Random is also in there. The new API is compatible with the old Random method, so you can also use the new API to call the Random class to generate Random numbers.

/ / using the Random
RandomGeneratorFactory<RandomGenerator> l128X256MixRandom = RandomGeneratorFactory.of("Random");
// Use a timestamp as a seed for random numbers
RandomGenerator randomGenerator = l128X256MixRandom.create(System.currentTimeMillis());
for (int i = 0; i < 5; i++) {
    System.out.println(randomGenerator.nextInt(10));
}
Copy the code

Extended reading: Enhanced pseudorandom number generator

3. JEP 382: Use the new macOS rendering library

In September 2018, macOS abandoned the OpenGL rendering library in favor of Apple Metal to improve graphics rendering performance. Java 17 starts supporting Apple Metal with this update, but there are no API changes. These are all internal changes.

MacOS Mojave 10.14 Release Notes, Apple Metal

4. JEP 391: Supports macOS/AArch64 architecture

The reason was that Apple announced at WWDC in June 2020 that it would start a long-term plan to transition the Macintosh computer family from X64 to AArch64, so it needed to get JDK support for macOS/AArch64 as soon as possible.

AArch64 is supported on Linux and already in Java 16, as you can see in the previous article.

Extension: New Java 16 features introduced – JEP 386

5. JEP 398: Delete deprecated Applet apis

An Applet is a small application written in Java that can be embedded in HTML through the ordinary HTML markup syntax, which is so outdated that it is hardly used in any scenario.

Example: Embed hello.class

<applet code="Hello.class" height=200 width=200></applet>
Copy the code

The Applet API was deprecated in Java 9 and will now be completely removed in Java 17.

6. JEP 403: Stronger JDK internals

To improve JDK security, change the default mode of the –illegal-access option from allow to deny, as described in JEP 396 of Java 16. With this change, JDK internal packages and apis (except for key internal apis) will no longer be opened by default.

In Java 17, however, with the exception of Sun.misc. Unsafe, using the –illegal-access command does not enable strong encapsulation within the JDK, except for the Sun.misc. Unsafe API.

Using the –illegal-access option in Java 17 will result in a warning that the command has been removed.

➜  bin ./java -version
openjdk version "17" 2021-09-14
OpenJDK Runtime Environment (build 17+35-2724)
OpenJDK 64-Bit Server VM (build 17+35-2724, mixed mode, sharing)
➜  bin ./java --illegal-access=warn
OpenJDK 64-Bit Server VM warning: Ignoring option --illegal-access=warn; support was removed in 17.0
Copy the code

JEP 403: Stronger JDK Internals, Introduction to New Java 16 features

7. JEP 406: Switch Type Matching (preview)

As with Instanceof, automatic conversion of type matches has been added to Switch.

Previously, using instanceof required the following:

if (obj instanceof String) {
    String s = (String) obj;    // grr.... }Copy the code

Redundant type cast, and now:

if (obj instanceof String s) {
    // Let pattern matching do the work!. }Copy the code

Switch can use a similar approach.

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();
    };
}
Copy the code

There are also new ways to determine null values.

// Before Java 17
static void testFooBar(String s) {
    if (s == null) {
        System.out.println("oops!");
        return;
    }
    switch (s) {
        case "Foo"."Bar" -> System.out.println("Great");
        default           -> System.out.println("Ok"); }}// Java 17
static void testFooBar(String s) {
    switch (s) {
        case null         -> System.out.println("Oops");
        case "Foo"."Bar" -> System.out.println("Great");
        default           -> System.out.println("Ok"); }}Copy the code

Read more: JEP 406: Switch Type Matching (Preview)

8. JEP 407: Remove RMI Activation

Remote Method Invocation (RMI) Activation flagged in JEP 385 has been removed, but the rest of the RMI will not be affected.

RMI Activation JEP 385 in Java 15 has been marked obsolete and has received no adverse feedback so far and the decision has been made to officially remove it in Java 17.

Read more: JEP 407: Removing RMI Activation

9. JEP 409: Sealed Classes

Sealed Classes (JEP 360), Sealed Classes (JEP 397), Sealed Classes (JEP 397), Sealed Classes (JEP 360) Want to know can refer to the previous article.

JEP 409: Sealed Classes

10. JEP 401: Removed experimental AOT and JIT compilers

In JEP 295 of Java 9, the experimental pre-compile JAOTC tool was introduced, but this feature has not been very useful since the introduction of dependencies and requires a lot of maintenance work, so it was decided to remove this feature in Java 17.

Three major JDK modules have been removed:

  1. JDK. Aot-jaotc tool.
  2. Piler-graal compiler.
  3. jdk.internal.vm.compiler.management

It also removed some HotSpot code related to AOT compilation:

  1. src/hotspot/share/aot— dumps and loads AOT code
  2. Additional code guarded by #if INCLUDE_AOT

11. JEP 411: Deprecating Security Manager

Security Manager was introduced in JDK 1.0, but it has never been the primary means of protecting server-side and client-side Java code. In order for Java to continue to evolve, it has been decided that Security Manager will be deprecated and removed in the near future.

@Deprecated(since="17", forRemoval=true)
public class SecurityManager {
	// ...
}
Copy the code

12. JEP 412: External Functions and Memory API (Incubation)

The new API allows Java developers to interact with code and data outside the JVM by calling external functions to call local libraries without using JNI.

This is an incubation function; You need to add--add-modules jdk.incubator.foreignTo compile and run Java code.

history

  • Java 14 JEP 370 introduces an external memory access API (incubator).
  • Java 15 JEP 383 introduces an external memory access API (the second incubator).
  • Java 16 JEP 389 introduces the external linker API (incubator).
  • Java 16 JEP 393 introduced an external memory access API (third incubator).
  • Java 17 JEP 412 introduces external functions and a memory API (incubator).

Read more: JEP 412: External Functions and Memory APIS (Incubation)

13. JEP 414: Vector API (Secondary Incubation)

A new API for vector computation was introduced in Java 16 that can reliably compile at run time into the supported CPU architecture for better computing power.

The Vector API has now been improved in Java 17, with features such as character manipulation and conversions between byte vectors and Boolean arrays.

JEP 415: Specifies the deserialization filter for the context

Serialization has always been an important feature in Java. Without serialization, Java might not have become the dominant development language. Serialization makes remote processing easy and transparent, and contributes to the success of Java EE.

But Java serialization is also fraught with problems, making almost every conceivable mistake and creating ongoing maintenance for developers. But there’s nothing wrong with serialization. The ability to transform objects into something that can be transferred freely between JVMS and rebuilt at the other end is a perfectly reasonable idea. The problem is that serialization design in Java is risky enough to expose a number of serialization related bugs.

One reason deserialization is dangerous is that sometimes it is not easy to verify that the content being deserialized is at risk, and the incoming data stream is free to reference the object, most likely as malicious code carefully constructed by an attacker.

Therefore, JEP 415 allows a filter configuration during deserialization to inform the class that the deserialization operation is allowed or prohibited. If a prohibited class is encountered during deserialization, the deserialization will fail.

14.1. Deserialization example

Assume that the Poc in the Dog class is a maliciously constructed class, but normal deserialization can succeed.

package com.wdbyte.java17;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

/ * * *@author niulang
 */
public class JEP415 {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        Dog dog = new Dog("Husky");
        dog.setPoc(new Poc());
        // serialize - object to byte array
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);) {
            objectOutputStream.writeObject(dog);
        }
        byte[] bytes = byteArrayOutputStream.toByteArray();
        // deserialize - byte array to object
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
        ObjectInputStream objectInputStream = newObjectInputStream(byteArrayInputStream); Object object = objectInputStream.readObject(); System.out.println(object.toString()); }}class Dog implements Serializable {
    private String name;
    private Poc poc;

    public Dog(String name) {
        this.name = name;
    }

    @Override
    public String toString(a) {
        return "Dog{" + "name='" + name + '\' ' + '} ';
    }
		// get... set...
}

class Poc implements Serializable{}Copy the code

Output result:

Dog{name=' husky '}Copy the code

14.2. Deserialize filters

In Java 17, you can customize deserialization filters to intercept disallowed classes.

package com.wdbyte.java17;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputFilter;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

/ * * *@author niulang
 */
public class JEP415 {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        Dog dog = new Dog("Husky");
        dog.setPoc(new Poc());
        // serialize - object to byte array
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);) {
            objectOutputStream.writeObject(dog);
        }
        byte[] bytes = byteArrayOutputStream.toByteArray();
        // deserialize - byte array to object
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
        ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
        // Allow com.wdbyte.java17.Dog class, allow all classes in java.base, deny any other classes
        ObjectInputFilter filter = ObjectInputFilter.Config.createFilter(
                        "com.wdbyte.java17.Dog; java.base/*; ! *"); objectInputStream.setObjectInputFilter(filter); Object object = objectInputStream.readObject(); System.out.println(object.toString()); }}class Dog implements Serializable {
    private String name;
    private Poc poc;

    public Dog(String name) {
        this.name = name;
    }

    @Override
    public String toString(a) {
        return "Dog{" + "name='" + name + '\' ' + '} ';
    }
		// get... set...
}

class Poc implements Serializable{}Copy the code

Deserialization will get an exception.

Exception in thread "main" java.io.InvalidClassException: filter status: REJECTED
	at java.base/java.io.ObjectInputStream.filterCheck(ObjectInputStream.java:1412)
	at java.base/java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:2053)
	at java.base/java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1907)
	....
Copy the code

Read more: JEP 415: Specify context deserialization filter

reference

  1. Openjdk.java.net/projects/jd…
  2. Docs.oracle.com/en/java/jav…

After < >

The article is constantly updated, you can search “program Ape Alang” on wechat or visit “program ape Alang blog” to read it for the first time. This article Github.com/niumoo/Java… Welcome to Star!