Skip to content

Commit 801c220

Browse files
committed
[feat] Java14新特性重构
1 parent e7e8d48 commit 801c220

File tree

1 file changed

+131
-107
lines changed

1 file changed

+131
-107
lines changed

docs/java/new-features/一文带你看遍JDK9到14的重要新特性.md

Lines changed: 131 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ Optional.ofNullable(cache.getIfPresent(key))
285285

286286
为了最大限度地减少 Full GC 造成的应用停顿的影响,从 Java10 开始,G1 的 FullGC 改为并行的标记清除算法,同时会使用与年轻代回收和混合回收相同的并行工作线程数量,从而减少了 Full GC 的发生,以带来更好的性能提升、更大的吞吐量。
287287

288-
### 应用程序类数据共享(扩展CDS功能)
288+
### 应用程序类数据共享(扩展 CDS 功能)
289289

290290
在 Java 5 中就已经引入了类数据共享机制 (Class Data Sharing,简称 CDS),允许将一组类预处理为共享归档文件,以便在运行时能够进行内存映射以减少 Java 程序的启动时间,当多个 Java 虚拟机(JVM)共享相同的归档文件时,还可以减少动态内存的占用量,同时减少多个虚拟机在同一个物理或虚拟的机器上运行时的资源占用。CDS 在当时还是 Oracle JDK 的商业特性。
291291

@@ -513,7 +513,7 @@ Java12 为默认的垃圾收集器 G1 带来了两项更新:
513513

514514
传统的 `switch` 语法存在容易漏写 `break` 的问题,而且从代码整洁性层面来看,多个 break 本质也是一种重复
515515

516-
Java12 提供了 `swtich` 表达式,使用类似 lambda 语法条件匹配成功后的执行块,不需要多写 break 。
516+
Java12 增强了 `swtich` 表达式,使用类似 lambda 语法条件匹配成功后的执行块,不需要多写 break 。
517517

518518
```java
519519
switch (day) {
@@ -553,30 +553,30 @@ if(obj instanceof String str){
553553

554554
#### 文本块
555555

556-
解决 Java 定义多行字符串时只能通过换行转义或者换行连接符来变通支持的问题,引入**三重双引号**来定义多行文本
556+
解决 Java 定义多行字符串时只能通过换行转义或者换行连接符来变通支持的问题,引入**三重双引号**来定义多行文本
557557

558-
两个`"""`中间的任何内容都会被解释为字符串的一部分,包括换行符。
558+
Java 13 支持两个 `"""` 符号中间的任何内容都会被解释为字符串的一部分,包括换行符。
559559

560560
未支持文本块之前的 HTML 写法:
561561

562-
```java
563-
String json ="{\n" +
564-
" \"name\":\"mkyong\",\n" +
565-
" \"age\":38\n" +
566-
"}\n";
567-
```
562+
```java
563+
String json ="{\n" +
564+
" \"name\":\"mkyong\",\n" +
565+
" \"age\":38\n" +
566+
"}\n";
567+
```
568568

569569
支持文本块之后的 HTML 写法:
570570

571-
```java
572-
573-
String json = """
574-
{
575-
"name":"mkyong",
576-
"age":38
577-
}
578-
""";
579-
```
571+
```java
572+
573+
String json = """
574+
{
575+
"name":"mkyong",
576+
"age":38
577+
}
578+
""";
579+
```
580580

581581
未支持文本块之前的 SQL 写法:
582582

@@ -598,9 +598,9 @@ String query = """
598598

599599
另外,`String` 类新增加了 3 个新的方法来操作文本块:
600600

601-
- `formatted(Object... args)` :它类似于 `String`` format() `方法。添加它是为了支持文本块的格式设置。
601+
- `formatted(Object... args)` :它类似于 `String``format()`方法。添加它是为了支持文本块的格式设置。
602602
- `stripIndent()` :用于去除文本块中每一行开头和结尾的空格。
603-
- `translateEscapes()` :转义序列如 *\\\t”* 转换为 *“\t”*
603+
- `translateEscapes()` :转义序列如 _\\\t”_ 转换为 _“\t”_
604604

605605
由于文本块是一项预览功能,可以在未来版本中删除,因此这些新方法被标记为弃用。
606606

@@ -610,14 +610,14 @@ public String stripIndent() {
610610
}
611611
@Deprecated(forRemoval=true, since="13")
612612
public String formatted(Object... args) {
613-
613+
614614
}
615615
@Deprecated(forRemoval=true, since="13")
616616
public String translateEscapes() {
617617
}
618618
```
619619

620-
#### Switch(引入 yield 关键字到 Switch 中)
620+
#### 增强 Switch(引入 yield 关键字到 Switch 中)
621621

622622
`Switch` 表达式中就多了一个关键字用于跳出 `Switch` 块的关键字 `yield`,主要用于返回一个值
623623

@@ -645,7 +645,7 @@ ZGC 堆由一组称为 ZPages 的堆区域组成。在 GC 周期中清空 ZPages
645645

646646
Java Socket API 终于迎来了重大更新!
647647

648-
Java 13 将 Socket API 的底层进行了重写, `NioSocketImpl` 是对 ``PlainSocketImpl`` 的直接替代,它使用 `java.util.concurrent` 包下的锁而不是同步方法。如果要使用旧实现,请使用 `-Djdk.net.usePlainSocketImpl=true`
648+
Java 13 将 Socket API 的底层进行了重写, `NioSocketImpl` 是对 `PlainSocketImpl` 的直接替代,它使用 `java.util.concurrent` 包下的锁而不是同步方法。如果要使用旧实现,请使用 `-Djdk.net.usePlainSocketImpl=true`
649649

650650
并且,在 Java 13 中是默认使用新的 Socket 实现,使其易于发现并在排除问题同时增加可维护性
651651

@@ -675,120 +675,143 @@ $ java -XX:SharedArchiveFile=my_app_cds.jsa -cp my_app.jar
675675

676676
## Java14
677677

678-
### record 关键字
679-
680-
- 简化数据类的定义方式,使用 record 代替 class 定义的类,只需要声明属性,就可以在获得属性的访问方法,以及 toString,hashCode,equals 方法
681-
682-
- 类似于使用 Class 定义类,同时使用了 lomobok 插件,并打上了`@Getter,@ToString,@EqualsAndHashCode`注解
683-
684-
- 作为预览特性引入
685-
686-
```java
687-
/**
688-
* 这个类具有两个特征
689-
* 1. 所有成员属性都是final
690-
* 2. 全部方法由构造方法,和两个成员属性访问器组成(共三个)
691-
* 那么这种类就很适合使用record来声明
692-
*/
693-
final class Rectangle implements Shape {
694-
final double length;
695-
final double width;
696-
697-
public Rectangle(double length, double width) {
698-
this.length = length;
699-
this.width = width;
700-
}
701-
702-
double length() { return length; }
703-
double width() { return width; }
704-
}
705-
/**
706-
* 1. 使用record声明的类会自动拥有上面类中的三个方法
707-
* 2. 在这基础上还附赠了equals(),hashCode()方法以及toString()方法
708-
* 3. toString方法中包括所有成员属性的字符串表示形式及其名称
709-
*/
710-
record Rectangle(float length, float width) { }
711-
```
712-
713678
### 空指针异常精准提示
714679

715-
- 通过 JVM 参数中添加`-XX:+ShowCodeDetailsInExceptionMessages`,可以在空指针异常中获取更为详细的调用信息,更快的定位和解决问题
680+
通过 JVM 参数中添加`-XX:+ShowCodeDetailsInExceptionMessages`,可以在空指针异常中获取更为详细的调用信息,更快的定位和解决问题
716681

717-
```java
718-
a.b.c.i = 99; // 假设这段代码会发生空指针
719-
```
682+
```java
683+
a.b.c.i = 99; // 假设这段代码会发生空指针
684+
```
720685

721-
```java
722-
Exception in thread "main" java.lang.NullPointerException:
723-
Cannot read field 'c' because 'a.b' is null.
724-
at Prog.main(Prog.java:5) // 增加参数后提示的异常中很明确的告知了哪里为空导致
725-
```
686+
Java 14 之前:
726687

727-
### switch 的增强终于转正
688+
```java
689+
Exception in thread "main" java.lang.NullPointerException
690+
at NullPointerExample.main(NullPointerExample.java:5)
691+
```
728692

729-
- JDK12 引入的 switch(预览特性)在 JDK14 变为正式版本,不需要增加参数来启用,直接在 JDK14 中就能使用
730-
- 主要是用`->`来替代以前的`:`+`break`;另外就是提供了 yield 来在 block 中返回值
693+
Java 14 之后:
731694

732-
_Before Java 14_
695+
```java
696+
// 增加参数后提示的异常中很明确的告知了哪里为空导致
697+
Exception in thread "main" java.lang.NullPointerException:
698+
Cannot read field 'c' because 'a.b' is null.
699+
at Prog.main(Prog.java:5)
700+
```
701+
702+
### switch 的增强(转正)
703+
704+
Java12 引入的 switch(预览特性)在 Java14 变为正式版本,不需要增加参数来启用,直接在 JDK14 中就能使用。
705+
706+
Java12 为 switch 表达式引入了类似 lambda 语法条件匹配成功后的执行块,不需要多写 break ,Java13 提供了 `yield` 来在 block 中返回值。
733707

734708
```java
735-
switch (day) {
736-
case MONDAY:
737-
case FRIDAY:
738-
case SUNDAY:
739-
System.out.println(6);
740-
break;
741-
case TUESDAY:
742-
System.out.println(7);
743-
break;
744-
case THURSDAY:
745-
case SATURDAY:
746-
System.out.println(8);
747-
break;
748-
case WEDNESDAY:
749-
System.out.println(9);
750-
break;
751-
}
709+
String result = switch (day) {
710+
case "M", "W", "F" -> "MWF";
711+
case "T", "TH", "S" -> "TTS";
712+
default -> {
713+
if(day.isEmpty())
714+
yield "Please insert a valid day.";
715+
else
716+
yield "Looks like a Sunday.";
717+
}
718+
719+
};
720+
System.out.println(result);
752721
```
753722

754-
_Java 14 enhancements_
723+
### 预览新特性
724+
725+
#### record 关键字
726+
727+
简化数据类的定义方式,使用 `record` 代替 `class` 定义的类,只需要声明属性,就可以在获得属性的访问方法,以及 `toString()``hashCode()`, `equals()`方法
728+
729+
类似于使用 `class` 定义类,同时使用了 lomobok 插件,并打上了`@Getter,@ToString,@EqualsAndHashCode`注解
755730

756731
```java
757-
switch (day) {
758-
case MONDAY, FRIDAY, SUNDAY -> System.out.println(6);
759-
case TUESDAY -> System.out.println(7);
760-
case THURSDAY, SATURDAY -> System.out.println(8);
761-
case WEDNESDAY -> System.out.println(9);
732+
/**
733+
* 这个类具有两个特征
734+
* 1. 所有成员属性都是final
735+
* 2. 全部方法由构造方法,和两个成员属性访问器组成(共三个)
736+
* 那么这种类就很适合使用record来声明
737+
*/
738+
final class Rectangle implements Shape {
739+
final double length;
740+
final double width;
741+
742+
public Rectangle(double length, double width) {
743+
this.length = length;
744+
this.width = width;
745+
}
746+
747+
double length() { return length; }
748+
double width() { return width; }
762749
}
750+
/**
751+
* 1. 使用record声明的类会自动拥有上面类中的三个方法
752+
* 2. 在这基础上还附赠了equals(),hashCode()方法以及toString()方法
753+
* 3. toString方法中包括所有成员属性的字符串表示形式及其名称
754+
*/
755+
record Rectangle(float length, float width) { }
763756
```
764757

765-
### instanceof 增强
758+
#### 文本块
759+
760+
Java14 中,文本块依然是预览特性,不过,其引入了两个新的转义字符:
761+
762+
- `\` : 表示行尾,不引入换行符
763+
- `\s` :表示单个空格
764+
765+
```java
766+
String str = "凡心所向,素履所往,生如逆旅,一苇以航。";
767+
768+
String str2 = """
769+
凡心所向,素履所往, \
770+
生如逆旅,一苇以航。""";
771+
System.out.println(str2);// 凡心所向,素履所往, 生如逆旅,一苇以航。
772+
String text = """
773+
java
774+
c++\sphp
775+
""";
776+
System.out.println(text);
777+
//输出:
778+
java
779+
c++ php
780+
```
781+
782+
#### instanceof 增强
766783

767784
依然是**预览特性** ,Java 12 新特性中介绍过。
768785

769-
### 其他特性
786+
### Java14 其他特性
770787

771788
- 从 Java11 引入的 ZGC 作为继 G1 过后的下一代 GC 算法,从支持 Linux 平台到 Java14 开始支持 MacOS 和 Window(个人感觉是终于可以在日常开发工具中先体验下 ZGC 的效果了,虽然其实 G1 也够用)
772-
- 移除了 CMS 垃圾收集器(功成而退)
789+
- 移除了 CMS(Concurrent Mark Sweep) 垃圾收集器(功成而退)
773790
- 新增了 jpackage 工具,标配将应用打成 jar 包外,还支持不同平台的特性包,比如 linux 下的`deb``rpm`,window 平台下的`msi``exe`
774791

775792
## 总结
776793

777794
### 关于预览特性
778795

779-
- 先贴一段 oracle 官网原文:`This is a preview feature, which is a feature whose design, specification, and implementation are complete, but is not permanent, which means that the feature may exist in a different form or not at all in future JDK releases. To compile and run code that contains preview features, you must specify additional command-line options.`
780-
- 这是一个预览功能,该功能的设计,规格和实现是完整的,但不是永久性的,这意味着该功能可能以其他形式存在或在将来的 JDK 版本中根本不存在。 要编译和运行包含预览功能的代码,必须指定其他命令行选项。
781-
- 就以`switch`的增强为例子,从 Java12 中推出,到 Java13 中将继续增强,直到 Java14 才正式转正进入 JDK 可以放心使用,不用考虑后续 JDK 版本对其的改动或修改
782-
- 一方面可以看出 JDK 作为标准平台在增加新特性的严谨态度,另一方面个人认为是对于预览特性应该采取审慎使用的态度。特性的设计和实现容易,但是其实际价值依然需要在使用中去验证
796+
先贴一段 oracle 官网原文:`This is a preview feature, which is a feature whose design, specification, and implementation are complete, but is not permanent, which means that the feature may exist in a different form or not at all in future JDK releases. To compile and run code that contains preview features, you must specify additional command-line options.`
797+
798+
这是一个预览功能,该功能的设计,规格和实现是完整的,但不是永久性的,这意味着该功能可能以其他形式存在或在将来的 JDK 版本中根本不存在。 要编译和运行包含预览功能的代码,必须指定其他命令行选项。
799+
800+
就以`switch`的增强为例子,从 Java12 中推出,到 Java13 中将继续增强,直到 Java14 才正式转正进入 JDK 可以放心使用,不用考虑后续 JDK 版本对其的改动或修改
801+
802+
一方面可以看出 JDK 作为标准平台在增加新特性的严谨态度,另一方面个人认为是对于预览特性应该采取审慎使用的态度。特性的设计和实现容易,但是其实际价值依然需要在使用中去验证
783803

784804
### JVM 虚拟机优化
785805

786-
- 每次 Java 版本的发布都伴随着对 JVM 虚拟机的优化,包括对现有垃圾回收算法的改进,引入新的垃圾回收算法,移除老旧的不再适用于今天的垃圾回收算法等
787-
- 整体优化的方向是**高效,低时延的垃圾回收表现**
788-
- 对于日常的应用开发者可能比较关注新的语法特性,但是从一个公司角度来说,在考虑是否升级 Java 平台时更加考虑的是**JVM 运行时的提升**
806+
每次 Java 版本的发布都伴随着对 JVM 虚拟机的优化,包括对现有垃圾回收算法的改进,引入新的垃圾回收算法,移除老旧的不再适用于今天的垃圾回收算法等
807+
808+
整体优化的方向是**高效,低时延的垃圾回收表现**
809+
810+
对于日常的应用开发者可能比较关注新的语法特性,但是从一个公司角度来说,在考虑是否升级 Java 平台时更加考虑的是**JVM 运行时的提升**
789811

790-
## 参考信息
812+
## 参考资料
791813

814+
- JDK Project Overview : <https://openjdk.java.net/projects/jdk/ >
792815
- IBM Developer Java9 <https://www.ibm.com/developerworks/cn/java/the-new-features-of-Java-9/>
793816
- Guide to Java10 <https://www.baeldung.com/java-10-overview>
794817
- Java 10 新特性介绍<https://www.ibm.com/developerworks/cn/java/the-new-features-of-Java-10/index.html>
@@ -800,4 +823,5 @@ switch (day) {
800823
- New Java13 Features <https://www.baeldung.com/java-13-new-features>
801824
- Java13 新特性概述 <https://www.ibm.com/developerworks/cn/java/the-new-features-of-Java-13/index.html>
802825
- Oracle Java14 record <https://docs.oracle.com/en/java/javase/14/language/records.html>
803-
- java14-features <https://www.techgeeknext.com/java/java14-features>
826+
- java14-features <https://www.techgeeknext.com/java/java14-features>
827+
- Java 14 Features : <https://www.journaldev.com/37273/java-14-features>

0 commit comments

Comments
 (0)