JDK11升级到JDK17在开发层面的新特性梳理
jdk17即将于今年9月发布,作为jdk11之后的又一个LTS版本,jdk17也会在未来作为生产环境的标配之一,那么这几年内jdk有哪些新特性呢,我们来梳理一下
考虑GC机制对普通开发者并不敏感,这里进行了省略
JDK11相对于JDK8的更新
尽管jdk17发布在即,使用jdk8的生产环境依然广泛存在,先回顾一下吧
集合加强(jdk9,jdk10,jdk11)
对所有的集合类型增加了of方法来创建静态集合
List<String> list = List.of("foo","bar");
Set<String> set = Set.of("foo","bar");
jdk10又增加了copyOf方法来复制一个不可改变集合
List<String> listA = List.of("foo","bar");
List<String> listB = List.copyOf(listA);
jdk11增加了toArray的重载方法,同时传入数组长度为0时可以自动扩充
// 旧的方法:传入String[]:
String[] oldway = list.toArray(new String[list.size()]);
// 新的方法:传入IntFunction:
String[] newway = list.toArray(String[]::new);
私有接口方法(jdk9)
可以在interface中定义private方法给default方法调用,在default方法中抽取方法又不想公开时可以这么写
IO加强(jdk9)
java.io.InputStream
中新增了方法便于读取和复制其中包含的数据
- readAllBytes: 读取所有剩余字节
- readNBytes: 读取指定数量的字节
- transferTo: 读取InputStream中的字节并直接写入对应的OutputStream
JShell工具(jdk9)
提供的小工具可以以控制台脚本的形式快速执行一段java表达式
Stream扩充(jdk9,jdk10)
新增了2个过程中方法:
- dropWhile: 按顺序遍历并丢弃,Predicate第一次返回false后开始读取
- takeWhile: 按顺序遍历并读取,Predicate第一次返回false后丢弃
注意在无序stream中可能产生不同的结果
新增两个static方法:
- ofNullable: 对于.of(),可避免空指针错误
- iterate: 新增异构方法,增加退出条件参数
Optional对象新增orElseThrow方法用于不存在时抛出异常
收集数据时增加了不可变集合的输出方式
list.stream().collect(Collectors.toUnmodifiableList());
list.stream().collect(Collectors.toUnmodifiableSet());
增加HttpClient实现(jdk9)
局部类型推断(jdk10,jdk11)
可以用var定义局部变量了,在jdk11中,var可用在lambda表达式中标识变量
读写文件优化(jdk11)
Files.writeString(
Path.of("./", "tmp.txt"), // 路径
"hello, jdk11 files api", // 内容
StandardCharsets.UTF_8); // 编码
String s = Files.readString(
Paths.get("./tmp.txt"), // 路径
StandardCharsets.UTF_8); // 编码
String API(jdk11)
String对象新增了若干方法
- strip: 类似trim(),但strip可去除unicode空格,如中文全角空格
- isBlank: 判断是不是空白字符串,可以识别unicode空格
- lines: 将文本按换行符拆分
- repeat: 指定文本重复次数并输出
JDK17新增特性
switch表达式(jdk12,jdk13,jdk14)
优化了switch表达式
//jdk12前
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;
}
//jdk12+
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);
}
//并且可以直接返回赋值
int numLetters = switch (day) {
case MONDAY, FRIDAY, SUNDAY -> 6;
case TUESDAY -> 7;
case THURSDAY, SATURDAY -> 8;
case WEDNESDAY -> 9;
};
java.text支持数字压缩格式(jdk12)
NumberFormat fmt = NumberFormat.getCompactNumberInstance(Locale.US, NumberFormat.Style.SHORT);
String result = fmt.format(1000);
//output 1K
文本块,多行文本(jdk13)
String query = """
SELECT `EMP_ID`, `LAST_NAME` FROM `EMPLOYEE_TB`
WHERE `CITY` = 'INDIANAPOLIS'
ORDER BY `EMP_ID`, `LAST_NAME`;
""";
FileSystems.newFileSystem方法(jdk13)
可以将文件内容视为文件系统的文件系统提供程序
nio新方法(jdk13)
java.nio.ByteBuffer
定义绝对批量get和put传输连续字节序列的方法,不考虑或影响缓冲区位置
java.time更新(jdk13)
更新了日本令和纪年Reiwa
record类型
record类型作为一个劣化的class类型,类似于C++中的struct,可替代简单的java bean/pojo对象
record Point (int x, int y){}
//等效于
class Point{
private final int x;
private final int y;
Point(int x,int y){
this.x = x;
this.y = y;
}
public int x(){
return x;
}
public int y(){
return y;
}
public boolean equals(Object o){
//...
}
public int hashCode(){
//...
}
public String toString(){
//...
}
}
instanceof优化(jdk14)
//java14前
if (obj instanceof String) {
String s = (String) obj;
// 使用s
}
//java14后
if (obj instanceof String s) {
// 使用s
}else{
//不可使用s
}
Unix-Domain Socket(jdk16)
支持基于Unix文件系统的socket,可用于同一主机的进程间通信,性能和安全性均高于TCP/IP socket
待续。。等jdk17发布再补充