从java 8 到 java 17 , 多个新特性整理
- 1. 1.集合工厂方法
- 2. 2.私有接口方法
- 3. 3.改进的进程 API
- 4. 4. 改进的 Stream API
- 5. 5. 改进的 try-with-resources
- 6. 6. 改进的 Optional 类
- 7. 7. 改进的 CompletableFuture API
- 8. 8. 支持使用var
- 9. 10. 字符串API加强
- 10. 11. 多行字符串
- 11. 12. 文本转义
- 12. 13. 文件读写更方便
- 13. 14. HttpClient
- 14. 15. switch表达式改进
- 15. 16. NumberFormat
- 16. 17. instanceof
- 17. 18. record
- 18. 19. sealed class 密封类
- 19. 其它更新
- 20. 官方参考
1.集合工厂方法
从Java 9开始, List,Set 和 Map 接口中,新的静态工厂方法可以创建这些集合的不可变实例。方便创建简单列表
代码示例:
1 | public static void main(String[] args){ |
输出结果
1 | [a, b, c] |
2.私有接口方法
在Java 8,接口可以有常量变量和抽象方法。我们不能在接口中提供私有方法的实现。现在接口越来越象抽象类了,意味着java通过这种方式变相的实现多继承。
示例代码
1 | public interface MyInterface { |
关键点:可以在 接口中使用 private 来定义私有接口
3.改进的进程 API
在 Java 9 之前,Process API 仍然缺乏对使用本地进程的基本支持,例如获取进程的 PID 和所有者,进程的开始时间,进程使用了多少 CPU 时间,多少本地进程正在运行等。
Java 9 向 Process API 添加了一个名为 ProcessHandle 的接口来增强 java.lang.Process 类。
示例代码:
1 | public static void main(String[] args) throws IOException { |
输出:
1 | 进程ID 25420 |
4. 改进的 Stream API
Java 9 为 Stream 新增了:dropWhile、takeWhile、ofNullable 方法,iterate 方法新增了一个重载方法。
示例代码:
1 | public static void main(String[] args){ |
输出结果:
1 | abc |
说明:
- takeWhile : 满足条件才执行,不满足则退出循环
- dropWhile : 第一次不满足条件才执行
- iterate : 方便创建流,可用于测试
- ofNullable: 防止空指针
5. 改进的 try-with-resources
从java7开始,支持了try-with-resources, 但在java 7 的时候,变量必须定义在try后的括号里。现在可以放出来了,使用更简单 示例代码
1 | public static void main(String[] args) throws IOException { |
6. 改进的 Optional 类
在 Java 9 中, Optional 添加了以下方法:
stream()
ifPresentOrElse()
orElse()
stream()
从Optional 中获取一个stream, 如果有值则返回该值的stream, 否则返回一个空的流,Stream.empty()。
示例代码:
1 | public static void main(String[] args){ |
输出结果:
1 | 0 |
ifPresentOrElse
定义
1 | public void ifPresentOrElse(Consumer<? super T> action, Runnable emptyAction) |
示例代码:
1 | public static void main(String[] args){ |
输出结果
1 | A |
orElse
如果optional有值,返回对应的值此,否则返回orElse里的内容 定义:
1 | public T orElse(T other) |
示例代码:
1 | public static void main(String[] args){ |
输出结果
1 | A |
7. 改进的 CompletableFuture API
新增了
- newIncompleteFuture
- defaultExecutor
- copy
- minimalCompletionStage
- completeAsync
- orTimeout
- completeOnTimeout
- delayedExecutor
- completedStage
- failedFuture
- failedStage
8. 支持使用var
从 java 10开始,引入了var 来声明局部变量 示例代码:
1 | var str = "Hi"; |
9. 删除的内容
Java 10 删除了很多工具:
- 命令行工具 javah,可以使用 javac -h 代替。
- 命令行选项 -X:prof,尽管可以使用 jmap 工具来访问分析信息。
一些从 Java1.2 开始标记的为已弃用的 API 也被永久删除了。包括 java.lang.SecurityManager.inCheck 字段和以下方法:
1 | java.lang.SecurityManager.classDepth(java.lang.String) |
整个 SecurityManager 类在 java 17 被标识为 弃用。在将来可能会删除。
JDK 10 也弃用了一些 API。
- java.security.acl 包已标记为已弃用,也包括 java.security 包中包含各种相关的类(Certificate,Identity,IdentityScope,Singer,auth.Policy)。
- javax.management.remote.rmi.RMIConnectorServer 类中的 CREDENTIAL_TYPES 被标记为不建议使用。
- java.io.FileInputStream 和 java.io.FileOutputStream 中的 finalize()方法已被标记为已弃用。所以在 java.util.zip.Deflater / Inflater / ZipFileclasses 中的 finalize()方法也被弃用。
10. 字符串API加强
isBlank()
从java 11 起开始支持,用来判断字符串里是否只包含空字符
定义:
1 | public boolean isBlank() |
示例代码:
1 | public static void main(String[] args){ |
输出结果
1 | true |
常见的空格,回车,换行,制表符 都会被识别为空白字符。
lines()
定义
1 | public Stream<String> lines() |
从java 11 起开始支持,按 \r \n 把符串转成stream.
示例代码:
1 | String str = "a\n b\r\rc"; |
输出结果
1 | 4 |
\r\n会只作为一个换行符。连续的 \r\n\r\n 就会识别为两行
strip()
定义
1 | public String strip() |
从java 11 起开始支持,去掉字符串前后的半角和全角空格,trim()只能去掉半角空格。stripLeading()是去掉左边的空格,stripTrailing()是去掉右边的空格
1 | String str = " Hello\u3000"; |
输出
1 | str = 7 |
repeat
定义
1 | public String repeat(int count) |
从java 11开始支持,重复当前字符串多次。可以用于日志输出时,输出多个分隔符,比如:======================
1 | String s = "="; |
indent
定义
1 | public String indent(int n) |
从java12开始支持,对字符串的每一行前面加n个空格。当n小于0时,就是去掉n个空格。并且在字符串的最后,会加上换行符。
代码示例
1 | String a = "hi"; |
输出结果
1 | [ hi |
formatted
定义:
1 | public String formatted(Object... args) |
从java 15开始支持。便于字符串本身就是格式化串时的使用,等价于String.format(this, args)
示例代码:
1 | String str = "hi %s"; |
输出结果
1 | hi 小明 |
11. 多行字符串
从java 15开始支持多行字符串,String类也增加了配套的方法。
1 | public static void main(String[] args){ |
输出结果
1 | <div> |
java17会自动把多行文本前面的缩进空格去掉。没有必要再用stripIndent()方法重复处理。
12. 文本转义
定义
1 | public String translateEscapes() |
从java 15开始支持,把字符串里的\n变成换行符,其它的\t \r 也同样支持。
示例代码:
1 | String str = "ha\\noo\\tkk"; |
输出结果
1 | ha\noo\tkk |
13. 文件读写更方便
java从1.7开始提供了Files工具类,java 11 增加了 writeString 和 readString,可以更方便的读写文本文件。
定义
1 | public static String readString(Path path) throws IOException |
默认使用的是UTF-8的编码,示例代码如下
1 | String dir= "C://tmp/hello.txt"; |
java 12 还增加了 mismatch 方法。对比两个文件,如果内容一致,会返回 -1 ,如果内容不同,会返回不同的字节开始位置。
14. HttpClient
java 11 支持了HttpClient, Http请求可以不用再引第三方包了。
1 | public static void main(String[] args) throws IOException, InterruptedException { |
15. switch表达式改进
可以把多个case写在一行了,通过 -> 来执行相关动作。
1 | String month = "june"; |
16. NumberFormat
方便输出数字格式化后的显示
1 | Locale locale = new Locale("zh", "CN"); |
输出内容:
1 | 100 |
如果把第一行改成美国的Locale
1 | Locale locale = new Locale("en", "US"); |
那么就会输出:
1 | 100 |
17. instanceof
java 14 简化了 instanceof 关键字的用法,现在你可以这样写
1 | Object obj = "abc"; |
18. record
record关键字,在java 17转正。它是和class, interface, enum 同类的关键字。 我们可以创建一个Point.java文件,里面就写:
1 | public record Point(int x,int y) {} |
然后就可以这样来使用了
1 | public class RecordTest { |
它适用于,简单不可变对象的封装。在某些场景下,可以替代lombok
19. sealed class 密封类
先看代码
1 | public sealed class Person permits Female, Male { |
上面我们定义了三个类,Person, Male 和 Female,即 人,男人,女人。 密封类就是增加了一种可能,明确定义某个类只能被指定的类继承。其它类无法对其进行继承。
从上面的例子我们看到 Person类前面使用了 sealed class 对其进行声明,在后面通过 permits 关键字指定了它只能被Female, Male这两个类进行继承。
Female, Male 这两个类在声明的时候必须指定它是final,还是 sealed ,还是non-sealed。如果指定为non-sealed,那么它就以可以被随意继承了。
看下面的代码:
1 | public sealed class Person permits Female, Male { |
这里我们把Male改为sealed修饰的类,指定其唯一子类 OldMale。但在声明 OldMale 指定为 non-sealed, 这么一来 OldMale 就又可以被随意的继承了。比如上面的 CityOldMale。
注意 上面的代码是5个类,我自己测试时是用了5个文件,大家可以自己试试以加深印象。
其它更新
在 Java 11 支持了 Unicode 10 之后, Java 12 支持了 Unicode 11,支持操作更多的表情、符号。
垃圾回收优化,引入 ZGC回收
java 14 移除了CMS(Concurrent Mark Sweep)垃圾收集器
官方参考
- https://openjdk.org/projects/jdk/17/
- https://openjdk.org/projects/jdk/16/
- https://openjdk.org/projects/jdk/15/
- https://openjdk.org/projects/jdk/14/
- https://openjdk.org/projects/jdk/13/
- https://openjdk.org/projects/jdk/12/
- https://openjdk.org/projects/jdk/11/
- https://openjdk.org/projects/jdk/10/
- https://openjdk.org/projects/jdk9/