Java 12 新特性

1. Switch 表达式扩展(预览功能)
传统的switch语句,容易漏写break而出错,同时写法并不简洁优雅。
Java 12之前
switch (day) {case MONDAY:case FRIDAY:case SUNDAY:System.out.println(6);break;case TUESDAY:System.out.println(7);break;case THURSDAY:case SATURDAY:System.out.println(8);break;case WEDNESDAY:System.out.println(9);break;}
JDk 12 之后,Switch表达式得到增强,能接受语句和表达式。
switch (day) {
case MONDAY, FRIDAY, SUNDAY -> System.out.println(6);
case TUESDAY -> System.out.println(7);
case THURSDAY, SATURDAY -> System.out.println(8);
case WEDNESDAY -> System.out.println(9);
}
2. 紧凑的数据格式
JDK 12 新增了NumberFormat对复杂数字的格式化
NumberFormat numberFormat = NumberFormat.getCompactNumberInstance(Locale.CHINA, NumberFormat.Style.SHORT);
System.out.println(numberFormat.format(100000));
//output
10万
3. 字符串支持transform、indent操作
transform 字符串转换,可以配合函数式接口Function一起使用
List<String> list1 = List.of("语雀", " 原子"); List<String> list2 = new ArrayList<>(); list1.forEach(element -> list2.add(element.transform(String::strip) .transform((e) -> "Hello," + e)) ); list2.forEach(System.out::println); //输出 Hello,语雀 Hello,原子indent 缩进,每行开头增加空格space和移除空格
String result = "Java\n Python\nC".indent(3); System.out.println(result); //输出 Java Python C4. Files.mismatch(Path, Path)
Java 12 新增了mismatch方法,此方法返回第一个不匹配的位置,如果没有不匹配,则返回 -1L。
public static long mismatch(Path path, Path path2) throws IOException;代码示例:
Path file1 = Paths.get("c:\\jay.txt"); Path file2 = Paths.get("c:\\语雀.txt"); try { long fileMismatch = Files.mismatch(file1, file2); System.out.println(fileMismatch); } catch (IOException e) { e.printStackTrace(); }5. Teeing Collector
Teeing Collector 是 Streams API 中引入的新的收集器实用程序,它的作用是 merge 两个 collector 的结果,API格式如下:
public static <T, R1, R2, R> Collector<T, ?, R> teeing(Collector<? super T, ?, R1> downstream1, Collector<? super T, ?, R2> downstream2, BiFunction<? super R1, ? super R2, R> merger)
直接看代码例子吧,如下为求学生的平均分和总分的例子
List<Student> studentList= Arrays.asList(
new Student("jay", 90),
new Student("捡田螺的小男孩", 100),
new Student("捡表情的小男孩", 80)
);
String teeingResult=studentList.stream().collect(
Collectors.teeing(
Collectors.averagingInt(Student::getScore),
Collectors.summingInt(Student::getScore),
(s1,s2)-> s1+ ":"+ s2
)
);
System.out.println(teeingResult); //90:270
6.其他特性
- 支持unicode 11(684个新字符、11个新blocks、7个新脚本)
- JVM 常量 API (主要在新的java.lang.invoke.constant包中定义了一系列基于值的符号引用类型,能够描述每种可加载常量。)
- Shenandoah GC(低暂停时间垃圾收集器)
- G1 收集器提升 (可中止的混合收集集合、及时返回未使用的已分配内存)
- 默认CDS档案
- JMH 基准测试
Java 13 新特性
1.Switch 表达式扩展(引入 yield 关键字)
传统的switch:
private static String getText(int number) {
String result = "";
switch (number) {
case 1, 2:
result = "one or two";
break;
case 3:
result = "three";
break;
case 4, 5, 6:
result = "four or five or six";
break;
default:
result = "unknown";
break;
复制代码
Java 13之后,value break 语句不再被编译,而是用 yield 来进行值返回
private static String getText(int number) {
return switch (number) {
case 1, 2:
yield "one or two";
case 3:
yield "three";
case 4, 5, 6:
yield "four or five or six";
default:
yield "unknown";
};
}
2.文本块升级
Java 13之前,字符串不能够多行使用,需要通过换行转义或者换行连接符等等,反正就是好麻烦、好难维护。
String html = "<html>\n" +
" <body>\n" +
" <p>Hello, 语雀原子</p>\n" +
" </body>\n" +
"</html>\n";
Java 13之后,清爽多了~
String html = """
<html>
<body>
<p>Hello, 语雀原子</p>
</body>
</html>
""";
3. SocketAPI 重构
- 传统的Java Socket API(java.net.ServerSocket 和 java.net.Socket)依赖于SocketImpl 的内部实现
- 在 Java 13之前,通过使用 PlainSocketImpl 作为 SocketImpl 的具体实现。
- Java 13 中的新底层实现,引入 NioSocketImpl 的实现用以替换 SocketImpl 的 PlainSocketImpl 实现,此实现与 NIO(新 I/O)实现共享相同的内部基础结构,并且与现有的缓冲区高速缓存机制集成在一起。
一个Socket简单例子:
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class SocketAPITest {
public static void main(String[] args) {
try (ServerSocket serverSocket = new ServerSocket(8080)){
boolean runFlag = true;
while(runFlag){
Socket clientSocket = serverSocket.accept();
//搞事情
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
运行以上的实例,看下是否有以下关键词输出~
[class,load] sun.nio.ch.NioSocketImpl
4.FileSystems.newFileSystem新方法
FileSystems 类中添加了以下三种新方法,以便更容易地使用将文件内容视为文件系统的文件系统提供程序:
- 1、newFileSystem(Path)
- 2、newFileSystem(Path, Map
) - 3、newFileSystem(Path, Map
, ClassLoader)
5. 增强 ZGC 释放未使用内存
- ZGC 是Java 11 中引入的最为瞩目的垃圾回收特性,是一种可伸缩、低延迟的垃圾收集器。但是实际使用中,它不能够主动将未使用的内存释放给操作系统。
- Java 13 中对 ZGC 的改进,包括释放未使用内存给操作系统、支持最大堆大小为 16TB、JVM参数-XX:SoftMaxHeapSize 来软限制堆大小
6.其他特性
- 动态 CDS 存档, 扩展了 Java 10 中引入的类数据共享功能, 使用CDS 存档变得更容易。
- 文本块的字符串类新方法,如formatted(Object…args),stripIndent()等。
Java 14 新特性

1. instanceof模式匹配
instanceof 传统使用方式:
if (person instanceof Singer) {
Singer singer = (Singer) person;
singer.sing();
} else if (person instanceof Writer) {
Writer writer = (Writer) person;
writer.write();
}
Java 14 对 instanceof 进行模式匹配改进之后
if (person instanceof Singer singer) {
singer.sing();
} else if (person instanceof Writer writer) {
writer.write();
}
2.Record 类型(预览功能)
Java 14将Record 类型作为预览特性而引入,有点类似于Lombok 的@Data注解,看个例子吧:
public record Person(String name, int age) {
public static String address;
public String getName() {
return name;
}
}
反编译结果:
public final class Person extends java.lang.Record {
private final java.lang.String name;
private final java.lang.String age;
public Person(java.lang.String name, java.lang.String age) { /* compiled code */ }
public java.lang.String getName() { /* compiled code */ }
public java.lang.String toString() { /* compiled code */ }
public final int hashCode() { /* compiled code */ }
public final boolean equals(java.lang.Object o) { /* compiled code */ }
public java.lang.String name() { /* compiled code */ }
public java.lang.String age() { /* compiled code */ }
}
可以发现,当用 Record 来声明一个类时,该类将自动拥有下面特征:
- 构造方法
- hashCode() 方法
- euqals() 方法
- toString() 方法
-
3. Switch 表达式-标准化
switch 表达式在之前的 Java 12 和 Java 13 中都是处于预览阶段,终于在 Java 14 标准化,成为稳定版本。
Java 12 为switch 表达式引入Lambda 语法
- Java 13 使用yield代替 break 关键字来返回表达式的返回值。
String result = switch (day) { case "M", "W", "F" -> "MWF"; case "T", "TH", "S" -> "TTS"; default -> { if (day.isEmpty()) { yield "Please insert a valid day."; } else { yield "Looks like a Sunday."; } } }; System.out.println(result);4. 改进 NullPointerExceptions提示信息
Java 14 之前: ```java String name = song.getSinger().getSingerName()
//堆栈信息 Exception in thread “main” java.lang.NullPointerException at NullPointerExample.main(NullPointerTest.java:6)
Java 14,通过引入JVM 参数`-XX:+ShowCodeDetailsInExceptionMessages`,<br />可以在空指针异常中获取更为详细的调用信息。
Exception in thread “main” java.lang.NullPointerException: Cannot invoke “Singer.getSingerName()” because the return value of “rainRow.getSinger()” is null at NullPointerExample.main(NullPointerTest.java:6) 复制代码
<a name="abf66162"></a>
####
<a name="2Cn2A"></a>
#### 5. 其他特性
- G1 的 NUMA 可识别内存分配
- 删除 CMS 垃圾回收器
- GC 支持 MacOS 和 Windows 系统
---
<a name="X7ZnI"></a>
### Java 15 新特性

<a name="wOEcs"></a>
#### 1.EdDSA 数字签名算法
- 使用 Edwards-Curve 数字签名算法(EdDSA)实现加密签名。
- 与其它签名方案相比,EdDSA 具有更高的安全性和性能。
- 得到许多其它加密库(如 OpenSSL、BoringSSL)的支持。
<a name="Qs4VT"></a>
#### <br />
<a name="zvXRZ"></a>
#### 2.Sealed Classes(封闭类,预览)
封闭类,可以是封闭类、封闭接口,防止其他类或接口扩展或实现它们。
```java
public abstract sealed class Singer
permits Jay, Eason{
...
}
类Singer被sealed 修饰,是封闭类,只能被2个指定子类(Jay, Eason)继承。
3. Hidden Classes(隐藏类)
- 隐藏类天生为框架设计的。
-
4. Remove the Nashorn JavaScript Engine
Nashorn太难维护了,移除 Nashorn JavaScript引擎成为一种必然
- 其实早在JDK 11 中就已经被标记为 deprecated 了。
5.Reimplement the Legacy DatagramSocket API(重新实现DatagramSocket API)
- 重新实现老的DatagramSocket API
更改java.net.DatagramSocket 和 java.net.MulticastSocket 为更加简单、现代化的底层实现。
6.其他
Disable and Deprecate Biased Locking(准备禁用偏向锁)
- instanceof 自动匹配模式(预览)
- ZGC,一个可伸缩、低延迟的垃圾回收器。(转正)
- Text Blocks,文本功能转正(JDK 13和14预览,14终于转正)
- Remove the Solaris and SPARC Ports(删除 Solaris 和 SPARC 端口)
- 外部存储器访问 API(允许Java 应用程序安全有效地访问 Java 堆之外的外部内存。)
- Record类型二次预览(在Java 14就预览过啦)
