diff --git a/source/_posts/nf-java10.md b/source/_posts/nf-java10.md index 770f9d1..6181c97 100644 --- a/source/_posts/nf-java10.md +++ b/source/_posts/nf-java10.md @@ -29,6 +29,7 @@ date: 2021-05-20 17:11:56 - {% post_link nf-java14 %} - {% post_link nf-java15 %} - {% post_link nf-java16 %} +- {% post_link nf-java17 %} ## 局部变量类型推断 diff --git a/source/_posts/nf-java11.md b/source/_posts/nf-java11.md index 06384b1..d9465cd 100644 --- a/source/_posts/nf-java11.md +++ b/source/_posts/nf-java11.md @@ -28,6 +28,7 @@ Java 11是于Java 8之后的第一个LTS(长期支持)版本,虽然距离J - {% post_link nf-java14 %} - {% post_link nf-java15 %} - {% post_link nf-java16 %} +- {% post_link nf-java17 %} ## 新字符串操作方法 @@ -116,4 +117,4 @@ Java是一门编译型语言,所以哪怕整个程序只有一个文件,也 - Java Mission Control - JavaFX -这些已经被移除的API现在都被转移到了第三方管理,不再集成在JDK中了,所以在挑选第三方库的时候,需要注意第三方库是否有使用这些内容。如果使用了这些被移除的内容,那么就要做一些兼容性处理了。 \ No newline at end of file +这些已经被移除的API现在都被转移到了第三方管理,不再集成在JDK中了,所以在挑选第三方库的时候,需要注意第三方库是否有使用这些内容。如果使用了这些被移除的内容,那么就要做一些兼容性处理了。 diff --git a/source/_posts/nf-java12.md b/source/_posts/nf-java12.md index b3002af..14cf7ea 100644 --- a/source/_posts/nf-java12.md +++ b/source/_posts/nf-java12.md @@ -27,6 +27,7 @@ Java 12也是两个LTS版之间的小进化版本,这个版本带来的变化 - {% post_link nf-java14 %} - {% post_link nf-java15 %} - {% post_link nf-java16 %} +- {% post_link nf-java17 %} ## 新字符串方法 @@ -77,4 +78,4 @@ Java 12带来了一票预览版功能,但是这些功能默认是不能够使 - `switch`现在可以使用新语法了,并且不再是一个语句,而是一个拥有值的表达式。 - `instanceOf`操作符现在不仅可以断言类型,还可以在断言为真的时候直接声明一个完成了类型转换的变量。 -- 引入了一个实验性的GC:Shenandoah。 \ No newline at end of file +- 引入了一个实验性的GC:Shenandoah。 diff --git a/source/_posts/nf-java13.md b/source/_posts/nf-java13.md index 4395a3a..8b4655b 100644 --- a/source/_posts/nf-java13.md +++ b/source/_posts/nf-java13.md @@ -27,6 +27,7 @@ Java 13是一个新功能比较贫瘠的版本,在Java 13中增加的功能基 - {% post_link nf-java14 %} - {% post_link nf-java15 %} - {% post_link nf-java16 %} +- {% post_link nf-java17 %} ## 预览功能 @@ -79,4 +80,4 @@ java -XX:SharedArchiveFile= -cp app.jar AppName 传统套接字API,诸如`java.net.Socket`和`java.net.ServerSocket`,在很早之前的Java版本中就已经存在了,而且在近20年中基本上没有发生过任何改变。所以在这个强调线程安全和异步的年代,这些比较古老的API就显得落后了。 -Java 13中借鉴了`java.nio`的内部结构,重新实现了`Socket`和`ServerSocket`。现在这两个类都已经在使用`java.nio`系列API做底层支持了。 \ No newline at end of file +Java 13中借鉴了`java.nio`的内部结构,重新实现了`Socket`和`ServerSocket`。现在这两个类都已经在使用`java.nio`系列API做底层支持了。 diff --git a/source/_posts/nf-java14.md b/source/_posts/nf-java14.md index ef8ec5e..1371787 100644 --- a/source/_posts/nf-java14.md +++ b/source/_posts/nf-java14.md @@ -30,6 +30,7 @@ Java 14带来了许多新功能,尤其是把之前一直处于预览状态的 - {% post_link nf-java14 %} - {% post_link nf-java15 %} - {% post_link nf-java16 %} +- {% post_link nf-java17 %} ## Switch表达式 @@ -186,4 +187,4 @@ assertEquals("John", user.username()); 在这套工具中,常用的有两个工具:`jlink`和`jpackage`。其中`jlink`主要用于JDK和JRE的裁剪,仅为程序保留程序运行所需的最小模块。`jpackage`主要用来对程序和裁剪过后的JRE进行打包,形成可执行文件(例如Windows中的`.exe`,macOS中的`.app`),并同时形成相应的安装包。 -打包工具的出现将极大的改变Java程序的发布和部署。 \ No newline at end of file +打包工具的出现将极大的改变Java程序的发布和部署。 diff --git a/source/_posts/nf-java15.md b/source/_posts/nf-java15.md index a57e0e9..5531aa8 100644 --- a/source/_posts/nf-java15.md +++ b/source/_posts/nf-java15.md @@ -28,6 +28,7 @@ Java 15同样也是一个短期支持版,其目的还是以功能稳定和功 - {% post_link nf-java14 %} - {% post_link nf-java15 %} - {% post_link nf-java16 %} +- {% post_link nf-java17 %} ## 隐藏类 diff --git a/source/_posts/nf-java16.md b/source/_posts/nf-java16.md index d68ab06..22c1814 100644 --- a/source/_posts/nf-java16.md +++ b/source/_posts/nf-java16.md @@ -28,6 +28,7 @@ Java 16是下一个LTS版本之前的最后一个发行版,有不少在两个L - {% post_link nf-java14 %} - {% post_link nf-java15 %} - {% post_link nf-java16 %} +- {% post_link nf-java17 %} ## 再述记录类 @@ -218,4 +219,4 @@ Unix-Domain Socket主要用于同一主机上的进程间通信(IPC)。Unix- - Vector - 外部链接器 -- 外部内存访问 \ No newline at end of file +- 外部内存访问 diff --git a/source/_posts/nf-java17.md b/source/_posts/nf-java17.md new file mode 100644 index 0000000..be7b0e3 --- /dev/null +++ b/source/_posts/nf-java17.md @@ -0,0 +1,140 @@ +--- +title: Java 17的新特性 +tags: + - JVM + - Java + - Java 17 + - 新特性 + - switch + - 密封类 +categories: + - - JVM + - Java +keywords: 'Java,Java 16,新特性,switch,模式匹配,AArch64,密封类,伪随机数生成器' +date: 2022-02-08 09:06:15 +--- + +Java 17是截止到目前最新的长期支持版(LTS),其实相对于之前的一个Java发行版本,Java 17引入的新特性并不多,而与日常应用中所密切相关的特性也是比较少的,更多的是使之前版本中处于预览和孵化状态的特性转正。 + +本系列的文章有: + +- {% post_link nf-java8 %} +- {% post_link nf-java9 %} +- {% post_link nf-java10 %} +- {% post_link nf-java11 %} +- {% post_link nf-java12 %} +- {% post_link nf-java13 %} +- {% post_link nf-java14 %} +- {% post_link nf-java15 %} +- {% post_link nf-java16 %} +- {% post_link nf-java17 %} + +## 恢复严格浮点模式 + +在Java 1.2以后,受处理器浮点运算性能的影响,也为了追求更好的浮点计算性能,Java采用了宽松的浮点模式。在宽松模式下,Java程序的浮点计算结果是由处理器决定的,而不是采用IEEE标准。例如Intel处理器的浮点计算精度为80bit,但IEEE标准的浮点精度为64bit,那么此时程序在做浮点运算的时候,计算结果就会与IEEE标准之间产生误差。这样推广出去,相同的程序在不同的硬件平台上,可能计算得到的浮点数结果相互之间都不一样,这就对程序计算结果的准确性造成了比较大的影响。 + +但是如果使用Java之前提供的`strictfp`关键字显式声明需要使用严格浮点模式,那么程序就会使用IEEE标准对浮点数据进行处理,这样一来在不同的硬件平台上,浮点计算的结果也就一致了。在Java 17以前,要在程序中使用严格浮点模式,必须显式使用`strictfp`关键字进行标记;在Java 17以后,程序进行浮点计算将默认采用严格模式,不必再手动使用`strictfp`开启严格模式了。 + +## 增强了伪随机数生成器 + +Java 17针对伪随机数生成器(PRNG)增加了一个新的`RandomGenerator`接口,这个接口为所有的PRNG算法提供了统一的API。新增的`RandomGenerator`接口的实例可以通过新增的`RandomGeneratorFactory`工厂类来构建。 + +例如以下是一个使用指定算法进行随机数生成的示例。 + +```java +RandomGeneratorFactory randomAlgorithm = RandomGeneratorFactory.of("L128X256MixRandom"); +RandomGenerator generator = randomAlgorithm.create(System.currentTimeMillis()); + +System.out.println(generator.nextInt(10)); +``` + +通过`RandomGeneratorFactory`提供的`all()`方法可以遍历出目前JDK中内置的所有PRNG算法。由于新的API中也内置了老的随机数生成器算法,所以使用新的API也是可以调用老的随机数生成器来生成随机数的。 + +## 提供了对于macOS/AArch64架构的支持 + +由于Apple在2020年的WWDC中宣布将会将Mac计算机从x64架构逐步过渡到AArch64架构,所以为了JDK的平台兼容性,必须引入对AArch64架构的支持。 + +如果开发者现在使用的是新款采用M1系列芯片的Mac笔记本,那么现在可以放心的安装使用Java 17了。 + +## 密封类 + +密封类在Java 15中被引入,现在在Java 17中已经正式转正。密封类相较于之前的Java版本中没有发生任何变化,所以可以直接按照之前Java 15新特性中的描述使用。 + +## 指定上下文的反序列化过滤器 + +序列化是Java中的一项重要功能,通过把对象转换为可以在JVM间自由传输并自动重新构建的能力让数据的远程处理变得更加便捷和透明。但是Java的序列化功能中漏洞也是非常多的,例如对象的反序列化就是一个比较危险的动作,因为传入的数据流可以自由的引用对象,而我们在使用这些内容的时候又不太容易对其进行验证,这样就给了攻击者通过伪造和构建攻击代码传入攻击数据流导致整个应用面临巨大的风险。 + +所以在Java 17中,支持在反序列化时,通过设置一个过滤配置,来通知JVM在本次反序列化的时候允许或者禁止操作的类,当反序列化的时候如果碰到了被禁止的类,那么整个反序列化过程就会失败。 + +例如我们有以下两个可以被序列化的类。 + +```java +@Data +@RequiredArgsConstructor +class Person implements Serializable { + @NonNull + private String name; + private Job job; +} + +@Data +@RequiredArgsConstructor +class Job implements Serializable { + @NonNull + private String name; +} +``` + +那么以下的反序列化操作就会失败。 + +```java +byte[] objectBytes = personBaos.toByteArray(); +ByteArrayInputStream bytesInputStream = new ByteArrayInputStream(objectBytes); +ObjectInputStream objectInputStream = new ObjectInputStream(bytesInputStream); +// 在这里设置反序列化的过滤器,当前语句的设置为允许 xyz.archgrid.demo.entity.person 类、 +// java.base 中的所有类,并拒绝其他任何类 +ObjectInputFilter filter = ObjectInputFilter.Config + .createFilter("xyz.archgrid.demo.entity.Person;java.base/*;!*"); +objectInputStream.setObjectInputFilter(filter); +Object object = objectInputStream.readObject(); +``` + +因为在示例中,`Person`类中使用了`Job`类的实例,但是`Job`类并没有在过滤器列表中列出,所以就会被拒绝。这段代码会抛出一个异常:`java.io.InvalidClassException: filter status: REJECTED`。 + +## 预览版功能 + +### Switch模式匹配 + +Switch表达式自从Java 12引入一来,一直在不断的改进和稳定中。在Java 17中,Switch表达式增加了可以用于匹配类型的模式匹配功能,也就是说Switch表达式可以使用类似于`instanceOf`的功能,来对被测量的内容进行判断。 + +例如可以使用以下这种复合的判断方式。 + +```java +String description = switch (someValue) { + case null -> "没有提供有效的值"; + case "test" -> "提供了一个字符串类型的测试值"; + case String s -> String.format("提供了一个字符串类型的测试值: [%s]", s); + case Integer i -> String.format("提供了一个整型的测试值: [%d]", i); + case Long l -> String.format("提供了一个长整型的测试值: [%d]", l); + case Double d -> String.format("提供了一个双精度浮点类型的测试值: [%f]", d); + default -> "没有列举对于指定类型的判断。"; +} +``` + +## 移除与废弃的功能 + +以下在之前的Java发布版中已经标记为废弃的API,在Java 17中已经被删除。 + +- Applet API。 +- RMI Activation。 +- 实验性的AOT和JIT编译器。 + +以下功能在Java 17中已经被标记为废弃,请尽量不要再使用。 + +- Security Manager。 + +## 孵化功能 + +- Vector,对于向量的计算功能,在Java 17中已经进入二次孵化的阶段,主要增强了对字符的操作以及字节向量与布尔数组之间的相互转换等功能。 +- 外部函数和内存API,这套新的API将允许开发者与JVM之外的代码和数据进行交互,可以在不使用JNI的情况下调用系统本地库。 + diff --git a/source/_posts/nf-java8.md b/source/_posts/nf-java8.md index e8b3370..7a5e02c 100644 --- a/source/_posts/nf-java8.md +++ b/source/_posts/nf-java8.md @@ -30,6 +30,7 @@ date: 2021-05-20 15:06:57 - {% post_link nf-java14 %} - {% post_link nf-java15 %} - {% post_link nf-java16 %} +- {% post_link nf-java17 %} ## Lambda表达式 diff --git a/source/_posts/nf-java9.md b/source/_posts/nf-java9.md index ba897cd..c210715 100644 --- a/source/_posts/nf-java9.md +++ b/source/_posts/nf-java9.md @@ -27,6 +27,7 @@ Java 9在Java 8的基础上做了许多重大的改进,尤其是引入了模 - {% post_link nf-java14 %} - {% post_link nf-java15 %} - {% post_link nf-java16 %} +- {% post_link nf-java17 %} ## Optional