likes look again, the power is unlimited. Hello world search "161887dae1e0e7 161887dae1e0e8 program ".

This article Github.com/niumoo/JavaNotes and unread code blog has been included, there are many knowledge points and series of articles.

image.png

Java 17 was officially released on September 14, 2021. Java 17 is a long-term support (LTS) version. This update brings a total of 14 new features.

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

OpenJDK Java 17 document: https://openjdk.java.net/projects/jdk/17/

<!-- more -->

JEPdescribe
JEP 306 Restore always strict floating-point semantics
JEP 356 Enhanced pseudo-random number generator
JEP 382 uses the new macOS rendering library
JEP 391 supports macOS/AArch64 architecture
JEP 398 Delete the enabled Applet API
JEP 403 Stronger package JDK internal package
JEP 406 Switch pattern matching (preview)
JEP 407 remove RMI Activation
JEP 409 Sealed Classes
JEP 410 JEP 401: Remove the experimental AOT and JIT compiler
JEP 411 Deprecate Security Manager
JEP 412 External function and memory API (Incubator)
JEP 414 Vector API (second incubator)
JEP 415 filter for the specified context
This article belongs to the Java new feature tutorial series. It will introduce the new features of each version of Java. You can click to browse.

1. JEP 306: Restore always strict floating-point semantics

Since it is the restoration of strict floating-point semantics, it means that before a certain point in time, it is always strict floating-point semantics. In fact, before Java SE 1.2, all floating-point calculations were strict, but based on the original situation, the excessively strict floating-point calculations were run on the popular x86 architecture and x87 floating-point protocol processors, which required a lot of Additional instruction overhead, so starting from Java SE 1.2, you need to manually use the keyword strictfp (strict float point) to enable strict floating point calculations.

But today in 2021, the hardware has undergone tremendous changes, and the original problem no longer exists, so starting from Java 17, the feature of always strict floating-point semantics has been restored.

extends : strictfp 161887dae1e5f2 is a keyword in Java. Most people may not have noticed it. It can be used in classes, interfaces, or methods that are modified by Perform strict floating point calculations.

The following is an example, where testStrictfp() is modified strictfp

package com.wdbyte;

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

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

2. JEP 356: Enhanced pseudo-random number generator

Added new interface types and implementations to the pseudorandom number generator RPNG (pseudorandom number generator), which makes it much easier to use various PRNG algorithms in the code.

This time, the RandomGenerator interface has been added, which provides a unified API for all PRNG algorithms, and can obtain different types of PRNG object streams. It also provides a new class RandomGeneratorFactory for constructing various RandomGenerator example, in RandomGeneratorFactory use ServiceLoader.provider to load various PRNG achieved.

The following is an example of usage: randomly choose 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");
        // 使用时间戳作为随机数种子
        RandomGenerator randomGenerator = l128X256MixRandom.create(System.currentTimeMillis());
        for (int i = 0; i < 5; i++) {
            System.out.println(randomGenerator.nextInt(10));
        }
    }
}

Get the output:

7
3
4
4
6

You can also traverse all PRNG algorithms.

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

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

You can see that Legacy:Random also in it. 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.

// 使用 Random
RandomGeneratorFactory<RandomGenerator> l128X256MixRandom = RandomGeneratorFactory.of("Random");
// 使用时间戳作为随机数种子
RandomGenerator randomGenerator = l128X256MixRandom.create(System.currentTimeMillis());
for (int i = 0; i < 5; i++) {
    System.out.println(randomGenerator.nextInt(10));
}
Extended reading: enhanced pseudo-random number generator

3. JEP 382: Use the new macOS rendering library

In order to improve the rendering performance of graphics, macOS abandoned the previous OpenGL rendering library in September 2018 and replaced it with Apple Metal. This update of Java 17 starts to support Apple Metal, but there is no change to the API. These are internal changes.

Extended reading: macOS Mojave 10.14 Release Notes , Apple Metal

4. JEP 391: Support macOS/AArch64 architecture

The reason is that Apple announced in the WWDC speech in June 2020 that it will start a long-term plan to transition the Macintosh computer series from x64 to AArch64. Therefore, it is necessary to let the JDK support macOS/AArch64 as soon as possible.

AArch64 support on Linux and already supported in Java 16, you can check the previous article to understand.

Extension: Java 16 New Features Introduction-JEP 386

5. JEP 398: Remove the deprecated Applet API

Applet is a small application written in Java that can be embedded in HTML. The embedding method is through ordinary HTML markup syntax. Since it is outdated, there are almost no scenes in use.

Example: Embed Hello.class

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

The Applet API has been marked obsolete in Java 9, and will now be completely removed in Java 17.

6. JEP 403: Stronger JDK internal packaging

As described in JEP 396 of Java 16, in order to improve the security of the JDK, --illegal-access option is changed from allow to deny. With this change, the internal packages and APIs of the JDK ( key internal API ) will no longer be opened by default.

However, in Java 17, except for sun.misc.Unsafe , using the --illegal-access command can not open the strong encapsulation mode inside the JDK, except for the sun.misc.Unsafe API.

--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
Extended reading: JEP 403: Stronger JDK internal package , Java 16 new function introduction

7. JEP 406: Type matching of switch (preview)

Like instanceof , the type matching automatic conversion function is also added switch

Before, the following operations instanceof

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

Superfluous type casting, and now:

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

switch can also be used in a similar way.

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

There are also new ways of judging the value of null

// 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");
    }
}
reading: 161887dae1ed34 JEP 406: Type matching of switch (preview)

8. JEP 407: Remove RMI Activation

Removed the RMI (Remote Method Invocation) Activation that was marked abolished in JEP 385, but other parts of RMI will not be affected.

The JEP 385 of RMI Activation in Java 15 has been marked as obsolete and has not received bad feedback so far, so it was decided to officially remove it in Java 17.

Extended reading: JEP 407: Remove RMI Activation

9. JEP 409: Sealed Classes

Sealed Classes was proposed in JEP 360 in Java 15, and JEP 397 in Java 16 is previewed again. Now Java 17 has become an official function. Compared with Java 16, there are no functional changes. I will not repeat the introduction here. I want to know You can refer to the previous article.

Extended reading: Java 16 New Features Introduction , JEP 409: Sealed Classes

10. JEP 401: Remove experimental AOT and JIT compilers

In Java 9 JEP 295, an experimental pre-compilation jaotc tool was introduced, but this feature is not very useful since the introduction of dependencies and requires a lot of maintenance work, so it was decided to delete this feature in Java 17.

Three main JDK modules have been removed:

  1. jdk.aot-jaotc tool.
  2. Jdk.internal.vm.compiler-Graal compiler.
  3. jdk.internal.vm.compiler.management

At the same time, some HotSpot codes related to AOT compilation are removed:

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

11. JEP 411: Deprecation of Security Manager

Security Manager has been introduced in JDK 1.0, but it has not been the main method to protect server and client Java code. For the continued development of Java, it was decided to abandon Security Manager and delete it in the near future.

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

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

The new API allows Java developers to interact with code and data outside the JVM. By calling external functions, they can call native libraries without using JNI.

This is an incubation function; --add-modules jdk.incubator.foreign needs to be added to compile and run Java code.

History

  • Java 14 JEP 370 introduced an external memory access API (incubator).
  • Java 15 JEP 383 introduced external memory access API (second incubator).
  • Java 16 JEP 389 introduced an external linker API (incubator).
  • Java 16 JEP 393 introduced external memory access API (third incubator).
  • Java 17 JEP 412 introduced external functions and memory API (incubator).
Extended reading: JEP 412: External Functions and Memory API (Incubating)

13. JEP 414: Vector API (Secondary Incubation)

A new API is introduced in Java 16 to perform vector calculations, which can be reliably compiled into a supported CPU architecture at runtime to achieve better computing power.

Now in Java 17, the performance of Vector API has been improved, and functions such as the operation of characters and the conversion between byte vectors and Boolean arrays have been enhanced.

14. JEP 415: Deserialization filter for specified context

Serialization in Java has always been a very important function. If there is no serialization function, Java may not occupy the dominant position of the development language. Serialization makes remote processing easy and transparent, and also promotes the success of Java EE. .

But there are many problems with Java serialization. It will make almost all imaginable mistakes and bring continuous maintenance work for developers. But it should be explained that the concept of serialization is not wrong. The ability to convert objects to be freely transmitted between JVMs and rebuild on the other end is a completely reasonable idea. The problem is that the serialization design in Java exists Risk, so much so that there have been many vulnerabilities related to serialization.

One reason for the danger of deserialization is that sometimes it is difficult for us to verify whether the content to be deserialized is at risk, and the incoming data stream can freely refer to objects. It is very likely that this data stream is maliciously constructed by the attacker. Code.

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

14.1. Deserialization example

Suppose the Poc in the Dog class is a maliciously constructed class, but normal deserialization can be successful.

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("哈士奇");
        dog.setPoc(new Poc());
        // 序列化 - 对象转字节数组
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);) {
            objectOutputStream.writeObject(dog);
        }
        byte[] bytes = byteArrayOutputStream.toByteArray();
        // 反序列化 - 字节数组转对象
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
        ObjectInputStream objectInputStream = new ObjectInputStream(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() {
        return "Dog{" + "name='" + name + '\'' + '}';
    }
        // get...set...
}

class Poc implements Serializable{

}

Output result:

Dog{name='哈士奇'}

14.2. Deserialization filter

In Java 17, you can customize the deserialization filter to intercept classes that are not allowed.

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("哈士奇");
        dog.setPoc(new Poc());
        // 序列化 - 对象转字节数组
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);) {
            objectOutputStream.writeObject(dog);
        }
        byte[] bytes = byteArrayOutputStream.toByteArray();
        // 反序列化 - 字节数组转对象
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
        ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
        // 允许 com.wdbyte.java17.Dog 类,允许 java.base 中的所有类,拒绝其他任何类
        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() {
        return "Dog{" + "name='" + name + '\'' + '}';
    }
        // get...set...
}

class Poc implements Serializable{
}

At this time, 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)
    ....
Extended reading: JEP 415: Deserialization filter for specified context

refer to

  1. https://openjdk.java.net/projects/jdk/17/
  2. https://docs.oracle.com/en/java/javase/17/

<end>

The article is continuously updated. You can search for " program or visit " Program " to read it for the first time. This article Github.com/niumoo/JavaNotes has been included, there are many knowledge points and series of articles, welcome to Star.

image.png


程序猿阿朗
376 声望1.8k 粉丝

Hello world :)