JDK9新特性
大约 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新特性官方文档
代码地址