Java9
新特性
红色:重要改变
绿色:语法改变
黄色:API改变
-
模块化系统
-
jShell命令
-
多版本兼容jar包
-
接口的私有方法
-
钻石操作符的使用升级
-
语法改进:try语句
-
String存储结构变更
-
便利的集合特性:of()
-
增强的StreamAPI
-
全新的HTTP客户端API
-
Deprecated的相关API
-
javadoc的HTML5支持
-
javaScript引擎升级:Nashorm
-
java的动态编译器
目录结构改变
java9之前
java9之后
模块化系统
jdk1.8之前,Java运行环境臃肿,每次JVM启动时,都会加载rt.jar到内存。系统并没有对不同部分之间的依赖关系
有个明确的概念。每一个公共类都可以被类路径下任何其他的公共类所访问到。这样就会导致无意中使用了并不想
被公开的API
本质上讲:模块的概念,其实就是package外再裹一层。不声明默认隐藏。所以模块化更加安全,因为可以指定哪些地方隐藏,哪些地方暴露
实现目标:
- 主要目的:减少内存开销
- 只须必要的模块,而非全部的jdk模块。简化大型应用的开发和维护
- 改进JavaSE平台
- 改进其安全性,可维护性,提高性能。
//创建module-info文件
//被调用者暴露接口
module java9Test {
exports com.strrysky.bean;
}
//调用者导入接口
module java9 {
requires java9Test;
}
Java的REPL工具——jShell命令
再jdk1.9之前,java版本想要执行代码,必须创建文件、声明类、测试方法才可以实现
设计理念
即写即得、快速运行
实现目标
- 让java像脚本语言一样运行,从控制台启动jShell,利用jShell在没有创建类的情况下直接声明变量、计算表达式、
- 执行语句。而无需创建java文件
- jShell可以从文件中加载语句,或者将将语句保存到文件
- jShell也可以是Tab键进行自动补全和自动添加分号
调出jShell:在jdk1.9以上的bin目录输入jshell,即可启动
可进行创建方法、创建类等各种操作。
默认已经导入以下包
常用操作:
操作 | 作用 |
---|---|
按TAB | 自动补全代码: |
/list | 列出当前session中所有有效片段: |
/vars | 查看当前session下所有创建过的变量: |
/methods | 查看当前session下所有创建过的方法: |
/edit add | 使用外部代码编辑器编写java代码: |
/open D:\jj.java | 运行外部java文件: |
/exit | 退出: |
接口的私有方法
jdk1.8中,接口可以有静态方法和默认的方法。一定程度上扩展了接口的功能。
jdk1.9中,接口可以有私有方法。
public interface MyInterface {
//必须重写
void methodAbstract();
//只能有接口类才可以调用
static void methodStatic(){
System.out.println("静态方法");
}
//可重写
default void methodDefault(){
System.out.println("默认方法");
}
//内部调用
private void methodPrivate(){
System.out.println("私有方法");
}
}
钻石操作符升级(<>)
<>与匿名内部类在jdk8中不能共存,但是在jdk9之后就可以
//在jdk9中,这样是正确的,但是在jdk8中是错误的,后面的<>也必须填入泛型
Comparator<Object> com = new Comparator<>() {
@Override
public int compare(Object o1, Object o2) {
return 0;
}
};
//jdk7新特性,类型推断
ArrayList<String> list = new ArrayList<>();
try-catch语法升级
Java 8 中,可以实现资源的自动关闭,但是要求执行后必须关闭的所有资源必 须在try子句中初始化,否则编译不
通过。如下例所示,但是在try里面,不能对变量进行更改,例如reader=null;
try(InputStreamReader reader = new InputStreamReader(System.in)){ //读取数据细节省略
}catch (IOException e){ e.printStackTrace();
}
在Java9中,可以在外部初始化,但是在try里面,不能对变量进行更改,例如reader=null;
因为此时的资源变量为常量,即final
public void imrove2(){
InputStreamReader reader = new InputStreamReader(System.in);
//将需要关闭的资源放到try括号里
//如有多个,用分号隔开,try(reader;writer)
try(reader) {
char[] buf = new char[20];
int len;
if((len = reader.read(buf))!=-1){
String str = new String(buf,0,len);
}
} catch (IOException e) {
e.printStackTrace();
}
}
String存储结构变更
String、StringBuilder、StringBuffer底层数组由char数组变为了byte数组
集合工厂方法(创建只读集合)
java9之前创建只读集合
//===========第一种
List<String> nameList = new ArrayList<>();
nameList.add("dd");
nameList.add("dd1");
nameList.add("dd2");
nameList = Collections.unmodifiableList(nameList);
System.out.println(nameList);
//===========第二种
List<Integer> list = Arrays.asList(1, 2, 3);
java9之后
List<Integer> list = List.of(1, 2, 3);
Set<Integer> set = Set.of(1, 1, 1);
Map<String, Integer> map = Map.of("Tom", 23, "Jer", 52);
Map<String, Integer> map2 = Map.ofEntries(Map.entry("Tmo", 12), Map.entry("dd", 30));
InputStream的加强
InputStream有了一个很有用的方法:transferTo,可以将数据直接传输到OutputStream
//示例代码未进行异常及资源关闭等处理
public static void main(String[] args) {
InputStream inputStream = new FileInputStream("你的名字.jpg");
OutputStream os = new FileOutputStream("你的命.jpg");
//相当于通过byte数组将流写入os中。
inputStream.transferTo(os);
}
增强的StreamAPI
Java9中,Stream接口中添加了4个方法:takeWhile、dropWhile、ofNUllable、还有一个iterate方法的重载方法
Optional和Stream之间的结合也得到了改进。现在可以通过Optional的新方法stream()将一个Optional对象转换
为一个(可能为空)的Stream对象。
方法 | 作用 |
---|---|
takeWhile | 返回从开头尽可能多的元素,满足条件的要,直到碰到不满足条件的,之后的全部舍去 |
dropWhile | 与takewhile相反,满足条件的不要,知道碰到不满足条件的,之后的全部要 |
ofNullable | 形参可以为空。如果为空,则stream为空流,里面没有元素 |
iterate重载 | 第二个参数为断言Predicate,即自定义终止条件。 |
takeWhile与dropWhile
public void test01() {
List<Integer> list = Arrays.asList(23, 46, 63, 5, 66, 1, 0, 8, 9, 60, 0, 10);
//takeWhile:返回从开头尽可能多的元素,满足条件的要,直到碰到不满足条件的,之后的全部舍去
//结果为:23,46
list.stream().takeWhile(x->x<60).forEach(System.out::println);
//与takewhile相反,满足条件的不要,知道碰到不满足条件的,之后的全部要
//返回剩余的元素
//结果为63, 5, 66, 1, 0, 8, 9, 60, 0, 10
list.stream().dropWhile(x->x<60).forEach(System.out::println);
}
ofNullable
public void test02() {
Stream<Integer> stream1 = Stream.of(1, 2, 3,null);
//stream1.forEach(System.out::println);输出1,2,3,元素个数为4
//不能只填充一个空值
//Stream<Integer> stream2 = Stream.of(null);//报错
Integer i =null;
//形参可以为空。如果为空,则stream为空流,里面没有元素
Stream<Integer> stream3 = Stream.ofNullable(i);//元素个数为0
stream3.forEach(System.out::println);
}
iterate重载
public void test03() {
//java8的写法
Stream.iterate(0,x->x+1).limit(10).forEach(System.out::println);
//java9的重载
//第二个参数为断言Predicate,即自定义终止条件。
Stream.iterate(0,x->x<100,x->x+1).forEach(System.out::println);
}
Optional的新方法
将Optional对象转为stream对象
public void test01() {
ArrayList<Object> list = new ArrayList<>();
list.add("tt");
list.add("tt2");
Optional<ArrayList<Object>> optional = Optional.ofNullable(list);
Stream<ArrayList<Object>> stream = optional.stream();
stream.flatMap(x->x.stream()).forEach(System.out::println);
}
JavaScript引擎升级:Nashorn
-
Nashorn 项目在 JDK 9 中得到改进,它为 Java 提供轻量级的 Javascript 运行时。 Nashorn 项目跟Netscape 的 Rhino 项目,目的是为了在 Java 中实现一个高 性能但轻量级的 Javascript 运行时。Nashorn 项目使得Java 应用能够嵌入 Javascript。它在 JDK 8 中为 Java提供一个 Javascript 引擎
-
JDK 9 包含一个用来解析 Nashorn 的 ECMAScript 语法树的 API。这个 API 使得 IDE 和服务端框架不需要依赖
Nashorn 项目的内部实现类,就能够分析 ECMAScript 代码。