总结一些Jdk8到Jdk17的一些新特性。
预览版:该功能在当前版本可以使用,如果效果不是很好的话,可能以后的其他版本就会删去该功能。
最终版:该功能在之前版本效果很好,之后的每个版本中都会存在该功能。

JDK8

Lambda

/**
* 匿名开启一个线程
*/
public static void jdk8Lambda() {
    new Thread(() -> System.out.println("-------------")).start();
}

Stream

Java 8 API添加了一个新的抽象称为流Stream,可以让你以一种声明的方式处理数据。

/**
* 去重
*/
public static void jdk8Stream() {
    List<String> list2 = new ArrayList<>();
    list2.add("aaa bbb ccc");
    list2.add("ddd eee fff");
    list2.add("ggg hhh iii");
    list2.add("ggg hhh iii");
    list2.stream().distinct().forEach(System.out::println);
}

Optional

Optional 类是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象。

/**
* optional
*/
public static void jdk8Optional() {
    // 1、创建一个包装对象值为空的Optional对象
    Optional<String> optStr = Optional.empty();
    // 2、创建包装对象值非空的Optional对象
    Optional<String> optStr1 = Optional.of("xiaofei");
    // 3、创建包装对象值允许为空的Optional对象
    Optional<String> optStr2 = Optional.ofNullable(null);
}

时间API

/**
* 时间API
*/
public static void jdk8DateTime() {
    // 获取当前年月日
    LocalDate localDate = LocalDate.now();
    System.out.println(localDate);
    // 获取当前时间
    LocalTime localTime = LocalTime.now();
    System.out.println(localTime);
    // 获取具体时间
    LocalDateTime localDateTime = LocalDateTime.now();
    System.out.println(localDateTime);
    // 字符串转换
    String str = "2022-01-01";
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    LocalDate localDate2 = LocalDate.parse(str, formatter);
    System.out.println(localDate2);
}

方法引用

/**
* 方法引用
*/
public static void jdk8Method() {
    List<String> names = new ArrayList();
    names.add("Xf");
    names.add("xiaofei");
    // 实例中我们将 System.out::println 方法作为静态方法来引用。
    names.forEach(System.out::println);
}

内置Base64

/**
* Base64
*/
public static void jdk8Base64() {
    // 使用基本编码
    String base64encodedString = null;
    try {
    base64encodedString = Base64.getEncoder().encodeToString("xiaofei".getBytes("utf-8"));
    System.out.println("Base64编码字符串:" + base64encodedString);
    // 解码
    byte[] base64decodedBytes = Base64.getDecoder().decode(base64encodedString);
    System.out.println("Base64解码字符串:" + new String(base64decodedBytes));
    } catch (UnsupportedEncodingException e) {
    e.printStackTrace();
    }
}

JDK9

接口可以添加私有方法

/**
 * 接口可以添加私有方法
 */
interface Jdk9Interface{

    default String defaultTest() {
        privateTest();
        return "default";
    }

    private String privateTest() {
        System.out.println("私有方法");
        return "private";
    }
}

异常处理try升级

Jdk8每一个流打开的时候都要关闭,但是在try的括号中来进行关闭。

Jdk9直接在括号里面写变量就可以关闭了。

/**
*  异常处理try升级
*/
public static void jdk9Try(){
    // jdk8:
    try(InputStreamReader reader =new InputStreamReader(System.in)){
    reader.read();
    }catch (IOException e){
    e.printStackTrace();
    }
    // jdk9以后:
    InputStreamReader reader =new InputStreamReader(System.in);
    try(reader){
    reader.read();
    }catch (IOException e){
    e.printStackTrace();
    }
}

增强钻石操作符 <>

/**
    * 增强钻石操作符 "<>"
    */
    public static void jdk9Diamonds(){
    // java7和8 <>没有了数据类型
    Map<String,String> map8 = new HashMap<>(1);
    // java9 添加了匿名内部类的功能 后面添加了大括号{}  可以做一些细节的操作
    Map<String,String> map9 = new HashMap<>(1){
    @Override
    public int size() {
    return 0;
    }
    };
}

增强了JDK8特性

增强了JDK8的特性如:Stream,Optional,Process API

引进HttpClient

以往我们都是通过maven添加httpclient ,java9直接引入即可。

JDK10

局部变量var

将前端思想var关键字引入java后段,自动检测所属于类型,一种情况除外,不能为null,因为不能判断具体类型,会报异常。

/**
* 局部变量var
*/
public static void jdk10Var() {
    var number = 10;
    var str    = "小飞博客";
    var list   = new ArrayList<>(1);
    var map    = new HashMap<>(1);
    var set    = new HashSet<>(1);
}

copyOf方法

在java.util.List、java.util.Set、java.util.Map新增加了一个静态方法copyOf,这些方法按照其迭代顺序返回一个不可修改的列表、集合或映射包含了给定的元素的集合。但是如果将返回后的集合继续修改,那么报异常。

/**
* copyOf方法
*/
public static void jdk10CopyOf() {
    var list = new ArrayList<>();
    list.add("first");
    list.add("second");
    list.add("third");
    var result = List.copyOf(list);
    System.out.println(result.toString());
}

垃圾收集器的优化

1、JDK9:新生代:ParNew收集器。 老年代:Parallel Old收集器

2、JDK10:G1(Garbage-First)全收集器

3、JDK10中含有垃圾收集器的可视化工具。在JDK安装目录的bin中 jmc.exe

JDK11

Lambda中使用 var

Consumer<String> consumer = (var t) ->System.out.println(t.toUpperCase());

字符串API增强

自JDK9和JDK10都为java增加了许多的API,如今JDK11又增加了许多字符串自带方法,如下

/**
* 局部变量var
*/
public static void jdk11String() {
    String str = "xiaofei ";
    // 判断字符串是空白
    boolean isblank = str.isBlank();
    // 判断字符串是否为空
    boolean isempty = str.isEmpty();
    // 首位空白
    String  result1 = str.strip();
    // 去除尾部空白
    String  result2 = str.stripTrailing();
    // 去除首部空白
    String  result3 = str.stripLeading();
    // 复制几遍字符串
    String  copyStr = str.repeat(2);
    // 行数统计
    long  lineCount = str.lines().count();

    System.out.println(isblank);
    System.out.println(isempty);
    System.out.println(result1);
    System.out.println(result2);
    System.out.println(result3);
    System.out.println(copyStr);
    System.out.println(lineCount);
}

结果:

false
false
xiaofei
xiaofei
xiaofei // 这里有空格
xiaofei xiaofei 
1

Process finished with exit code 0

javac + java命令合并

以前编译一个 java 文件时,需要先 javac 编译为 class,然后再用 java 执行,现在可以放到一起执行了。

$ java HelloWorld.java
Hello Java 11!

JDK12

1、Switch表达式(预览版)

Switch优化

/**
* Switch优化
*/
public static void jdk12Switch() {
    var day = 1;
    switch (day) {
    case 1, 2, 3 -> System.out.println(1);
    case 6 -> System.out.println(2);
    case 10, 11 -> System.out.println(3);
    case 20 -> System.out.println(4);
    }
}

instanceof + 类型强转

/**
* instanceof
*/
public static void jdk12Instanceofh() {
    Object obj = "XiaoFei";
    // jdk12之前
    if (obj instanceof String) {
        String s = (String) obj;
        int length = s.length();
        System.out.println(length);
    }
    // jdk12之后
    if (obj instanceof String str) {
        int length = str.length();
        System.out.println(length);
    }
}

JDK13

1、switch优化更新(预览版)

Switch优化

JAVA 12 中虽然增强了 swtich 语法,但并不能在 -> 之后写复杂的逻辑,JAVA 13 带来了 swtich可以直接返回信息到变量上面。

/**
* Switch优化
*/
public static void jdk13Switch() {
    int k = 2;
    String result = switch (k) {
    case  1 -> "one";
    case  2 -> "two";
    default -> "many";
    };
    System.out.println(result);
}

Switch优化

Java 13开始,文本块可用作预览功能。它们以三个双引号(”””)开头。

/**
* 文本块升级
*/
public static void jdk13Text() {
    // jdk13之前
    String html1 = "<html>\n" +
    "    <body>\n" +
    "        <p>Hello, world</p>\n" +
    "    </body>\n" +
    "</html>\n";
    // jdk13之后
    String html2 = """
    <html>
    <body>
    <p>Hello, world</p>
    </body>
    </html>
    """;
}

JDK14

1、Switch(最终版)
2、垃圾回收器(更新优化)
3、Record(预览功能)
4、instanceof的模式匹配(预览版)
5、jpackage 打包 (预览版)

新增Record

使用它可以替代构造器、equal方法、toString方法,hashCode方法。

public record Person(String name, int age) {}

新增Record

新增 jpackage 打包工具,直接打包二进制程序,再也不用装 JRE 了!

JDK15

1、jpackage 打包 (预览版)
2、文本块(最终版)
3、Record(第二预览版)
4、Sealed 类(第一预览版)

支持Unicode 13.0

此版本将Unicode支持升级到13.0,增加了13.0 5930个字符,总共143859个字符类支持Unicode字符数据库,以及55个新表情符号字符。

封闭 Sealed 类

sealed可以定义哪些其他类或接口可以扩展或实现当前类。

JDK16

1、Record(最终版)
2、密封类(第二预览版)
3、jpackage 打包 (最终版)

Stream新增toList方法

.collect(Collectors.toList());
.toList();

JDK17

1、Realed class密封类(最终版)

随机数增强

新加了一个类: RandomSupport,又一个 3000 行的 Java 文件。

var random = RandomGenerator.of("L32X64MixRandom");
for (int i = 0; i < 10; i++) {
    System.out.println(random.nextInt());
}