2017年9月JDK -9发布,官网声明:Oracle will not post further updates of Java SE 8 to its public download sites for commercial use after September 2018.尽早规划新版本的使用,不失为一种好的选择,本文着重介绍JDK9新特性
安装与环境变量配置
JDK9安装
JDK9较之前版本,目录结构和配置方面,稍有不同
首先下载最新版的JDK-9
安装方式与之前版本一样,没有任何差别,但安装后的目录结构不同,如下图所示
为了直观对比,下面贴出JDK8的目录结构,如下图所示
新版jdk目录中,没有jre文件夹了,这导致环境变量配置有所不同
JDK9配置
1 | JAVA_HOME=jdk安装路径 |
原来CLASSPATH里的几个jar包不需要再配置了,也找不到了,以下是JDK8配置1
2
3
4
5
6
7
8JAVA_HOME=jdk安装路径
PATH=$JAVA_HOME/bin
CLASSPATH=.:$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar
或
JAVA_HOME=jdk安装路径
JRE_HOME=jre安装路径
PATH=${JAVA_HOME}/bin
CLASSPATH=.;${JAVA_HOME}/lib:${JRE_HOME}/lib
IDEA配置JDK
file -> Project Structure -> SDKs -> 点击加号,然后选择JDK目录即可
JDK9 新特性
模块化
首先,我们创建一个普通的Java项目,然后创建一个模块 tools
IntelliJ IDEA 会引导你在工程中为你的模块创建一个module-info.java
之后,在需要使用ConvertUtils类的地方,进行模块引入即可
注意:模块引入可以由IntelliJ IDEA自动完成
如你所料,进行这个操作后IntelliJ IDEA对module-info.java文件进行了正确的更改
当然,也可以自己编辑module-info.java文件,IDEA 会有自动补全和提示信息
网络请求
Java 9 中有新的方式来处理 HTTP 调用。这个迟到的特性用于代替老旧的 HttpURLConnection
API,并提供对 WebSocket 和 HTTP/2 的支持。
注意:新的 HttpClient API 在 Java 9 中以所谓的孵化器模块交付。也就是说,这套 API 不能保证 100% 完成。不过你可以在 Java 9 中开始使用这套 API
module-info.java引入如下代码1
2
3module JDK9 {
requires jdk.incubator.httpclient;
}
1 | package com.cnlod.blog; |
更多HTTP/2使用方法,请参考《HTTP/2 Client API》
改进的 Stream API
长期以来,Stream API 都是 Java 标准库最好的改进之一。通过这套 API 可以在集合上建立用于转换的申明管道。在 Java 9 中它会变得更好。
Stream 接口中添加了 4 个新的方法:dropWhile, takeWhile, ofNullable。还有个 iterate 方法的新重载方法,
可以让你提供一个 Predicate (判断条件)来指定什么时候结束迭代:1
2
3
4
5public static void main(String[] args) {
IntStream.iterate(1,i -> i<10,i -> i+1).forEach(System.out::println);
Stream<Integer> it = Optional.of(2).stream();
System.out.println("=="+it.count());
}
集合工厂
通常,您希望在代码中创建一个集合(例如,List 或 Set ),并直接用一些元素填充它。 实例化集合,几个 “add” 调用,使得代码重复。
Java 9,添加了几种集合工厂方法1
2
3
4
5
6
7
8public static void main(String[] args) {
Set sets1 = Set.of();//空集合
System.out.println(sets1.size()+"==========");
Set<String> sets2 = Set.of("a","b","c");
System.out.println(sets2.size()+"---------");
List<String> lists1 = List.of("h","m","d");
System.out.println(lists1.size()+"++++++++++");
}
Java8:Optional类
这是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28public static void main(String[] args) {
/**
* 1.of方法通过工厂方法创建Optional类。需要注意的是,创建对象时传入的参数不能为null。如果传入参数为null,则抛出NullPointerException 。
*/
Optional<String> name = Optional.of("Andy");
/**
* 2.ofNullable与of方法相似,唯一的区别是可以接受参数为null的情况
* 为指定的值创建一个Optional,如果指定的值为null,则返回一个空的Optional。
*/
Optional empty = Optional.ofNullable(null);
//System.out.println(empty.isPresent()); //如果值存在返回true,否则返回false。
//3.如果Optional实例有值则为其调用consumer,否则不做处理
/*name.ifPresent((value) -> {
System.out.println(value);
});*/
//4.orElse:如果有值则将其返回,否则返回指定的其它值。
/*System.out.println(empty.orElse("没有值,采用此默认值!"));
System.out.println(name.orElse("有值,不采用此默认值!"));*/
/**
* 5.orElseGet:orElseGet与orElse方法类似,区别在于得到的默认值。
* orElse方法将传入的字符串作为默认值,orElseGet方法可以接受Supplier接口的实现用来生成默认值。示例如下:
*/
//System.out.println(empty.orElseGet(() -> "Default Value"));
//System.out.println(name.orElseGet(() -> "Default Value"));
}
Java8:接口中定义默认方法
1 | public interface MyInterface { |
1 | public class MyInterfaceImpl implements MyInterface { |
1 | public class MyInterfaceImpl2 implements MyInterface { |
Java8:eta-conversion
Java8开始支持ETA转换,代码更简洁,用::表示函数引用,比如静态方法的引用String::valueOf;比如构造器的引用,ArrayList::new等1
2
3for (Object n : list) { System.out.println(n); } # 普通循环
list.forEach(n -> System.out.println(n)); # lambda
list.forEach(System.out::println); ## ::引用