跳至主要內容

JDK9新特性

xw大约 7 分钟JAVAJAVA

概览

  • 模块系统
    • 引入了一个新的可选阶段,即链接时间(link time) ,它位于编译时和运行时之间,在此期间可以将一组模块组装并优化为一个定制的运行时映像;
  • 版本控制
    提供一种简化的版本字符串格式,有助于明确区分主版本、次版本、安全版本和修补程序更新版本。
$MAJOR.$MINOR.$SECURITY.$PATCH

MAJOR 主版本号
MINOR 小更新版本号
SECURITY 针对安全更新的版本号
PATCH 补丁版本号
  • 安装包新特性

    • Windows版本提供在安装程序的欢迎页中启用或禁用 web 部署的选项。
    • macOs提供关于卸载当前 CPU 版本后下一个 CPU 可用性的通知,在更新 JRE 时增强用户体验。
  • 工具新特性

    • jshell
    • 添加更多诊断命令
    • 删除启动时的 JRE 版本选择
    • 支持多版本JAR文件
    • 移除 hprof agent
    • 移除jhat
    • jlink(作用:将一组模块及其依赖关系组装并优化为自定义的运行时映像)
  • 安全方面

    • 数据传输层加密
    • TLS 应用层协议协商扩展
    • 支持 SHA-3加密散列函数
    • 将默认密钥存储类型从 JKS 转换为 PKCS12。
    • 禁止SHA-1证书
    • GHASH and RSA性能提升
  • Javadoc 新功能

    • 简化 Doclet API
    • 支持HTML5
    • javaDoc查询
    • 支持模块
  • JVM新特性

    • 分段代码缓存(将代码缓存划分为不同的段,每个段包含特定类型的已编译代码,以提高性能并启用未来的扩展)
    • 删除不推荐的GC组合
    • G1作为默认垃圾回收器
    • 不推荐使用CMS

Jshell

简介

JShell 是 Java 9 新增的一个交互式的编程环境工具。它允许你无需使用类或者方法包装来执行 Java 语句。它与 Python 的解释器类似,可以直接 输入表达式并查看其执行结果。

使用 Jshell

常用命令

jshell> /help
|  键入 Java 语言表达式, 语句或声明。
|  或者键入以下命令之一:
|  /list [<名称或 id>|-all|-start]
|       列出您键入的源
|  /edit <名称或 id>
|       编辑按名称或 id 引用的源条目
|  /drop <名称或 id>
|       删除按名称或 id 引用的源条目
|  /save [-all|-history|-start] <文件>
|       将片段源保存到文件。
|  /open <file>
|       打开文件作为源输入
|  /vars [<名称或 id>|-all|-start]
|       列出已声明变量及其值
|  /methods [<名称或 id>|-all|-start]
|       列出已声明方法及其签名
|  /types [<名称或 id>|-all|-start]
|       列出已声明的类型
|  /imports
|       列出导入的项
|  /exit
|       退出 jshell
|  /env [-class-path <路径>] [-module-path <路径>] [-add-modules <模块>] ...
|       查看或更改评估上下文
|  /reset [-class-path <路径>] [-module-path <路径>] [-add-modules <模块>]...
|       重启 jshell
|  /reload [-restore] [-quiet] [-class-path <路径>] [-module-path <路径>]...
|       重置和重放相关历史记录 -- 当前历史记录或上一个历史记录 (-restore)
|  /history
|       您键入的内容的历史记录
|  /help [<command>|<subject>]
|       获取 jshell 的相关信息
|  /set editor|start|feedback|mode|prompt|truncation|format ...
|       设置 jshell 配置信息
|  /? [<command>|<subject>]
|       获取 jshell 的相关信息
|  /!
|       重新运行上一个片段
|  /<id>
|       按 id 重新运行片段
|  /-<n>
|       重新运行前面的第 n 个片段
|
|  有关详细信息, 请键入 '/help', 后跟
|  命令或主题的名称。
|  例如 '/help /list' 或 '/help intro'。主题:
|
|  intro
|       jshell 工具的简介
|  shortcuts
|       片段和命令输入提示, 信息访问以及
|       自动代码生成的按键说明
|  context
|       /env /reload 和 /reset 的评估上下文选项

jshell> /help
|  键入 Java 语言表达式, 语句或声明。
|  或者键入以下命令之一:
|  /list [<名称或 id>|-all|-start]
|       列出您键入的源
|  /edit <名称或 id>
|       编辑按名称或 id 引用的源条目
|  /drop <名称或 id>
|       删除按名称或 id 引用的源条目
|  /save [-all|-history|-start] <文件>
|       将片段源保存到文件。
|  /open <file>
|       打开文件作为源输入
|  /vars [<名称或 id>|-all|-start]
|       列出已声明变量及其值
|  /methods [<名称或 id>|-all|-start]
|       列出已声明方法及其签名
|  /types [<名称或 id>|-all|-start]
|       列出已声明的类型
|  /imports
|       列出导入的项
|  /exit
|       退出 jshell
|  /env [-class-path <路径>] [-module-path <路径>] [-add-modules <模块>] ...
|       查看或更改评估上下文
|  /reset [-class-path <路径>] [-module-path <路径>] [-add-modules <模块>]...
|       重启 jshell
|  /reload [-restore] [-quiet] [-class-path <路径>] [-module-path <路径>]...
|       重置和重放相关历史记录 -- 当前历史记录或上一个历史记录 (-restore)
|  /history
|       您键入的内容的历史记录
|  /help [<command>|<subject>]
|       获取 jshell 的相关信息
|  /set editor|start|feedback|mode|prompt|truncation|format ...
|       设置 jshell 配置信息
|  /? [<command>|<subject>]
|       获取 jshell 的相关信息
|  /!
|       重新运行上一个片段
|  /<id>
|       按 id 重新运行片段
|  /-<n>
|       重新运行前面的第 n 个片段
|
|  有关详细信息, 请键入 '/help', 后跟
|  命令或主题的名称。
|  例如 '/help /list' 或 '/help intro'。主题:
|
|  intro
|       jshell 工具的简介
|  shortcuts
|       片段和命令输入提示, 信息访问以及
|       自动代码生成的按键说明
|  context
|       /env /reload 和 /reset 的评估上下文选项

举例


jshell> 1+2
$1 ==> 3

##创建方法
jshell> int add(int a,int b){return a+b;}
|  已创建 方法 a(int,int)

jshell> int aaa(int a,int b){return a+b;}
|  已创建 方法 aaa(int,int)

## 调用方法
jshell> a(1,2)
$4 ==> 3

jshell>

接口使用私有方法

接口:

package jdk9;

/**
 * @author by xw
 * @Description JDK9接口私有方案测试
 */
public interface InterfacePrivateMethod {

    void hello();

    /**
     * JDK8 允许接口有default方法
     */
    default void test()
    {
        privateMethod();
    }

    /**
     * JDK9 允许接口私有的实现方法
     */
    private void privateMethod() {
        System.out.println("interface private method test");
    }
}

实现类:

package jdk9;

/**
 * @author by xw
 * @Description TODO
 */
public class InterfacePrivateMethodImpl implements InterfacePrivateMethod{
    @Override
    public void hello() {

    }

    public static void main(String[] args) {
        InterfacePrivateMethod interfacePrivateMethod = new InterfacePrivateMethodImpl();
        interfacePrivateMethod.test();
    }
}

测试:
正常运行,输出

interface private method test
Process finished with exit code 0

增加 try-with-resources

在 JDK7 中,新增了 try-with-rsources 语句,可以在 try 的括号中初始化资源,可以实现资源自动关闭。

 /**
     * JDK7使用try-with-resources语句需要在try中初始化资源,
     * 可以实现自动释放
     *
     * @param filepath 路径
     * @throws FileNotFoundException
     */
    private void jdk7TryWithResource(String filepath) throws FileNotFoundException {
        OutputStream out = new FileOutputStream(filepath);
        try(OutputStream temp = out;)
        {
            temp.write((filepath+"可以学习java架构课程").getBytes()); }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

在JDK9中,改进了try-with-resources语句,在try外进⾏初始化,在括号内引⽤,即可实现 资源⾃动关闭,多个变量则⽤分号进⾏分割,不需要声明资源 out 就可以使⽤它,并得到相同的结果。

 /**
     * JDK9增强
     *
     *
     * @param filepath
     * @throws FileNotFoundException
     */
    private static void test(String filepath) throws FileNotFoundException {
        OutputStream out = new FileOutputStream(filepath);
        try (out) {
            out.write((filepath + "java9 try-with-resources test").getBytes());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

新增集合API

JDK9新增快速创建只读集合。

package jdk9;

import java.util.*;

/**
 * @author by xw
 * @Description 快速创建只读集合
 */
public class UnmodifiableListTest {

    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("1");
        list.add("2");
        list.add("3");
        //设置为只读List集合
        list = Collections.unmodifiableList(list);
        System.out.println(list);
        Set<String> set = new HashSet<>();
        set.add("1");
        set.add("2");
        set.add("3");
        //设置为只读Set集合
        set = Collections.unmodifiableSet(set);
        System.out.println(set);
        Map<String, String> map = new HashMap<>();
        map.put("key1", "1");
        map.put("key2", "2");
        //设置为只读Map集合
        map = Collections.unmodifiableMap(map);
        System.out.println(map);
    }
}

新增Strean API

1、takeWhile与dropWhile

  • 在有序的集合中,takeWhile从 Stream 中获取⼀部分数据, 返回从头开始的尽可能多的元素, 直到遇到第⼀ 个false结果,如果第⼀个值不满⾜断⾔条件,将返回⼀个空的 Stream,dropWhile效果与其相反
  • 在无序集合中,好像没什么实际的应用场景。。
package jdk9;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author by xw
 * @Description TODO
 */
public class AddStreamApi {

    public static void main(String[] args) {

        // 有序集合
        List<String> takeWhilelist =
                List.of("springboot", "java", "html", "", "git").stream().takeWhile(obj -> !obj.isEmpty()).collect(Collectors.toList());

        System.out.println("takewhile list " + takeWhilelist);

        // 无序集合
        Set<String> takewhileSet = List.of("springboot", "java", "html", "", "git").stream().takeWhile(obj -> !obj.isEmpty()).collect(Collectors.toSet());
        System.out.println("takewhile set" + takewhileSet);


        List<String> dropWhileList = List.of("springboot", "java", "html", "", "git").stream().dropWhile(obj -> !obj.isEmpty())
                .collect(Collectors.toList());
        System.out.println("dropwhile list" + dropWhileList);

        Set<String> dropWhileSet = List.of("springboot", "java", "html", "", "git").stream().dropWhile(obj -> !obj.isEmpty())
                .collect(Collectors.toSet());
        System.out.println("dropwhile set" + dropWhileSet);

    }
}

运行结果:

takewhile list [springboot, java, html]
takewhile set[java, html, springboot]
dropwhile list[, git]
dropwhile set[, git]

去掉jhat工具

jhat也是jdk内置的工具之一。主要是用来分析java堆的命令,可以将堆中的对象以html的形式显示出来,JDK9中已经移除该功能。

垃圾回收器更改

JDK9移除了下面回收器组合:

  • DefNew + CMS
  • ParNew + SerialOld
  • Incremental CMS

删除的命令行:

  • -Xincgc
  • -XX:+CMSIncrementalMode
  • -XX:+UseCMSCompactAtFullCollection
  • -XX:+CMSFullGCsBeforeCompaction
  • -XX:+UseCMSCollectionPassing

G1作为默认垃圾回收器,同时不推荐CMS并发标记进行垃圾回收

参考文档:
JDK9新特性官方文档open in new window
代码地址open in new window