Java篇-Java新特性概览

R-C.png

背景

持续更新记录Jvav(Java)的新版本特性和使用案例

JDK19

新版本总共包含 7 个新的 JEP:

405: Record Patterns (Preview)
422: Linux/RISC-V Port
424: Foreign Function & Memory API (Preview)
425: Virtual Threads (Preview)
426: Vector API (Fourth Incubator)
427: Pattern Matching for switch (Third Preview)
428: Structured Concurrency (Incubator)

虚拟线程

1
2
var virtualThread = Thread.ofVirtual().unstarted(() -> System.out.println(Thread.currentThread()));
virtualThread.start();

JDK18

JDK 18 共包括 9 个 JEP,以及数百个较小的增强功能和一千多个错误修复。

400: UTF-8 by Default
408: Simple Web Server
413: Code Snippets in Java API Documentation
416: Reimplement Core Reflection with Method Handles
417: Vector API (Third Incubator)
418: Internet-Address Resolution SPI
419: Foreign Function & Memory API (Second Incubator)
420: Pattern Matching for switch (Second Preview)
421: Deprecate Finalization for Removal

该版本中并没有增加很多新特性,只是对GC、加密、安全库、字符集、I/O做一些改进

JDK17

JDK/Java 17 总共包含 14 个 JEP,具体如下:

306: Restore Always-Strict Floating-Point Semantics
356: Enhanced Pseudo-Random Number Generators
382: New macOS Rendering Pipeline
391: macOS/AArch64 Port
398: Deprecate the Applet API for Removal
403: Strongly Encapsulate JDK Internals
406: Pattern Matching for switch (Preview)
407: Remove RMI Activation
409: Sealed Classes
410: Remove the Experimental AOT and JIT Compiler
411: Deprecate the Security Manager for Removal
412: Foreign Function & Memory API (Incubator)
414: Vector API (Second Incubator)
415: Context-Specific Deserialization Filters

sealed关键字

被 sealed 修饰,说明它是一个密封类,并且只允许指定的 子类继承。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.example.jdk17;
/*
* 由sealed修饰的类通过permits来控制可以减继承实现的类
*/
public abstract sealed class Shape
//允许实现的类
permits Circle, Rectangle {

}
public final class Rectangle extends Shape{

}
public final class Circle extends Shape{

}

//The type Start extending a sealed class Shape should be a permitted subtype of Shape
public final class Start extends Shape{

}

Stream类改进

Random类改进

JDK16

  1. Mentioned Below are Some of the New Features Added in Java 16:
  2. Foreign Linker API
  3. Warnings for Value-Based Classes
  4. Strong Encapsulation
  5. Moving Z Garbage Collector Thread-Stack Processing
  6. A Flexible Metaspace Capability
  7. Added C++ 14 Language Features
  8. Records Classes
  9. A Vector API
  10. Pattern Matching
  11. jpackage Tool for Packaging Self-Contained Java Applications.
  12. OpenJDK source code repositories Migration from Mercurial to Git.

JDK15

ZGC转正

JDK14

Record关键字

Java 编译器将为 record 类型生成 equals(),hashCode(),toString() 方法,以及生成适当的构造函数,并且为所有字段生成 getter 和 setter

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public record Point(double x, double y) { }
//等同于
public class Point {
private final double x;
private final double y;
public Point(double x, double y) {
this.x = x;
this.y = y;
}
public double getX() {
return x;
}
public double getY() {
return y;
}
}

有用信息空指针异常

通过 JVM 参数中添加

1
-XX:+ShowCodeDetailsInExceptionMessages

可以在空指针异常中获取更为详细的调用信息,更快的定位和解决问题。

接口类型匹配

1
2
3
4
if (o instanceof String) {
String s = (String)o;
System.out.println(s.length);
}

自动转换

1
2
3
4
Object o = null;
if (o instanceof String s) {
System.out.println(s.length());
}

JDK13

文本块

1
2
3
4
5
6
7
String htmlBlock = """
<html>
<body>
<p>My web page</p>
</body>
<html>
""";

String类增强

1
2
3
formatted(): This formats the string using the string itself as the format string and is equivalent to calling format(this, args)
stripIndent(): This removes incidental spaces from the string. This is useful if you are reading multi-line strings and want to apply the same elimination of incidental whitespace as happens with an explicit declaration.
translateEscapes(): This returns the string with escape sequences, (e.g. r) translated into the appropriate Unicode value.

JDK12

Switch 表达式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
var day = MONDAY;
int numLetters = 0;
switch (day) {
case MONDAY:
case FRIDAY:
case SUNDAY:
numLetters = 6;
break;
case TUESDAY:
numLetters = 7;
break;
case THURSDAY:
case SATURDAY:
numLetters = 8;
break;
case WEDNESDAY:
numLetters = 9;
break;
default:
throw new IllegalStateException("Huh? " + day);
}

新版本

1
2
3
4
5
6
7
int numLetters = switch (day) {
case MONDAY, FRIDAY, SUNDAY -> 6;
case TUESDAY -> 7;
case THURSDAY, SATURDAY -> 8;
case WEDNESDAY -> 9;
default -> throw new IllegalStateException("Huh? " + day);
};

JDK11

局部变量引入Lambda

1
2
3
list.stream()
.map((var s) -> s.toLowerCase())
.collect(Collectors.toList());

String类增强

1
2
3
4
5
6
boolean isBlank(): Returns true if the string is empty or contains only white space codepoints, otherwise false.
Stream lines(): Returns a stream of lines extracted from this string, separated by line terminators.
String repeat(int): Returns a string whose value is the concatenation of this string repeated count times.
String strip(): Returns a string whose value is this string, with all leading and trailing whitespace removed.
String stripLeading(): Returns a string whose value is this string, with all leading whitespace removed.
String stripTrailing(): Returns a string whose value is this string, with all trailing whitespace removed.

ZGC

这是一种新的实验性垃圾收集器,设计用于需要大(数GB)堆和低延迟的应用程序。它使用一个单代堆,并与应用程序同时执行大多数(但不是全部)GC工作。它通过使用一个读取屏障来实现这一点,该屏障拦截应用程序对对象的每次读取,并确保返回的引用是正确的。这消除了在应用程序线程运行时能够同时重新定位对象的问题。

ZGC基于区域(如G1),支持NUMA并进行压缩。它不打算用作通用收集器。

JDK10

var关键字

局部变量类型自动推断

1
2
var list = new ArrayList<String>();  // infers ArrayList<String>
var stream = list.stream(); // infers Stream<String>

集合增强

List,Set,Map 提供了静态方法copyOf()返回入参集合的一个不可变拷贝。

1
2
3
static <E> List<E> copyOf(Collection<? extends E> coll) {     
return ImmutableCollections.listCopy(coll);
}

G1并行Full GC

JDK9

接口中允许私有方法

1
2
3
4
5
interface Intf {
private void m(String s){
System.out.println(s);
}
}

集合工厂方法

1
2
3
Set<Integer> set = Set.of(1, 2, 3);
List<Integer> list = List.of(1, 2, 3);
Map<String, Integer> map = Map.of("one", 1, "two", 2);

try-with-resources 增强

jdk9之前只能在try-with-resources里声明变量

1
2
3
4
5
try (FileInputStream file = new FileInputStream("a.txt")){
file.read();
}catch (Exception e){
e.printStackTrace();
}

jdk9后可以在外面写

1
2
3
4
5
6
7
FileInputStream file = new FileInputStream("a.txt");
try (file){
file.read();
}catch (Exception e){
e.printStackTrace();
}

响应式流

新增了 java.util.concurrent.Flow

image.png

模块化

模块化的出现主要是为了减少包的大小,对不同模块的权限控制更加精细

1
2
3
4
5
[open] module <module> {        
<module-statement>;
<module-statement>;
...
}

open修饰符是可选的,它声明一个开放的模块。 一个开放的模块导出所有的包,以便其他模块使用反射访问。 是要定义的模块的名称。 是一个模块语句。 模块声明中可以包含零个或多个模块语句。 如果它存在,它可以是五种类型的语句之一:

  • 导出语句(exports statement);
  • 开放语句(opens statement);
  • 需要语句(requires statement);
  • 使用语句(uses statement);
  • 提供语句(provides statement)。

参考:https://openjdk.org/projects/jigsaw/quick-start

进程 API

新增了java.lang.ProcessHandle类获取进程相关信息

1
2
3
4
5
6
7
8
9

public class ProcessDemo {
public static void main(String[] args) {
// 获取当前正在运行的 JVM 的进程
ProcessHandle currentProcess = ProcessHandle.current();
System.out.println("进程pid ="+currentProcess.pid());
System.out.println("进程信息"+currentProcess.info());
}
}

image.png

Jshell

可实现java控制台代码交互式编程(类似输入脚本)
image.png

JDK8

函数式接口

该库位于java.util.function包下,可以将函数作为参数进行传递、运行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package java8;

import java.util.function.Function;

public class FunctionDemo {

public static void main(String[] args) {
Function<String, String> function = new Function<>() {
@Override
public String apply(String s) {
return String.format("modify %s",s);
}
};
System.out.println(function.apply("hello"));
m0(function);
}

public static void m0(Function<String,String> function){
String s = "hello";
function.apply(s);
//...
}
}

Lambda表达式

lambda语法糖减少一定的代码量,格式

1
(parameters) -> expression 或 (parameters) ->{ statements; }

Java 8 中 Consumer, Supplier, Predicate and Function的应用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class Lambda {
//接口
interface itf {
void m(String s);
}
public static void main(String[] args) {
itf itf0 = new itf() {
@Override
public void m(String s) {
System.out.println(s);
}
};
itf itf1 = s -> System.out.println(s);
itf0.m("hello0");
itf1.m("hello1");
}
}

Stream

该库位于java.util.stream包下

1
2
3
4
5
6
7
8
9
10
11
public class StreamDemo {
public static void main(String[] args) {
int[] arr = {1, 3, 3, 4, 4, 5, 55, 3};
Stream<String> stream = Stream.of(args);
stream.map(s -> s);//遍历元素执行function
stream.collect(Collectors.toList());//收集
stream.filter(s->s.equals(0));//过滤
stream.flatMapToInt(e-> IntStream.of(e.length())).forEach(System.out::println);//映射元素
}
}

Optional

Optional的出现是为了解决NPE问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import java.util.Optional;

public class OptionalDemo {
public static void main(String[] args) {
String s0 = null;
s0 = Optional.ofNullable(s0).orElse("hello");//如果s0是null则返回为hello
System.out.println(s0);//hello

String s1 = "abc";
s1 = Optional.ofNullable(s1).orElse("hello");//如果s1是null则返回为hello
System.out.println(s1);//abc

String s2 = null;
s2 = Optional.of(s2).orElse("hello");//如果s2是null则NPE
System.out.println(s2);

String s3 = "hi";
s3 = Optional.ofNullable(s3).map(s -> s.substring(1, 2)).orElse("Hi");
System.out.println(s3);
}
}

Date Time API

新增了LocalDateLocalDateTime

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class DateDemo {
public static void main(String[] args) {

LocalDate date = LocalDate.now();
date.isBefore(date);
String format = date.format(DateTimeFormatter.ISO_ORDINAL_DATE);
System.out.println(format);

LocalDateTime time = LocalDateTime.now();
int year = time.getYear();
System.out.println(year);
}
}

Nashorn javascript引擎

资料

jvav8:https://www.oracle.com/java/technologies/javase/8-whats-new.html
jvav18: https://www.oracle.com/java/technologies/javase/18-relnote-issues.html#NewFeature


Java篇-Java新特性概览
https://mikeygithub.github.io/2021/10/15/yuque/Java篇-Java新特性概览/
作者
Mikey
发布于
2021年10月15日
许可协议