本文原帖:https://mp.weixin.qq.com/s?__biz=MjM5ODIzNDQ3Mw==&mid=2649967585&idx=1&sn=9590c1e20660286695a2dca535a9530b&chksm=beca3be789bdb2f13c70e0e205089620b4dc9efdbf18fd3c8e046bec970da4a19de64fa01080&mpshare=1&scene=1&srcid=0923Gtsfo7O3jyX7Lcyy03jD&pass_ticket=rFbAsCoLC88PxvDhdSmo9F6%2F9R6YtLw8QrG9CV8%2FmPSHfTJUw4%2BMHi95ULu3yUYn#rd待字闺中公众号分享。
Java9经过诸多的坎坷终于发布,对于老Java程序员,颇激动,第一时间就要和大家分享这种激动,迅速下载JDK,做了第一个尝试,我想在这个尝试之前,大家心里都有这个痛。
一.安装
jdk9下载链接:http://www.oracle.com/technetwork/java/javase/downloads/jdk9-downloads-3848520.html。
把jdk-9_linux-x64_bin.tar.gz下载完后解压到某个位置,然后修改系统配置文件:
vi ~/.bashrc
加入以下内容:
export JAVA_HOME=/home/soft/jdk-9
export CLASSPATH=$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib
export PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH:$HOME/bin
然后使之生效:
source ~/.bashrc
然后
java --version
查看java版本,就可以查看到如下打印:
java version "9"
Java(TM) SE Runtime Environment (build 9+181)
Java HotSpot(TM) 64-Bit Server VM (build 9+181, mixed mode)
root@kerie-TianYi5060:/home/soft/jdk-9# jshell
| 欢迎使用 JShell -- 版本 9
| 要大致了解该版本, 请键入: /help intro
二.jshell尝试
如果你用过Python,里面的shell交互操作你肯定用过。只可惜在java9之前的版本并不支持这样的交互式操作,写个“hello world”也得这样:
public static void main(String[] args)
但是java9让这一去不复返,写个简单的测试操作不需要写.java文件了。
# jshell
| 欢迎使用 JShell -- 版本 9
| 要大致了解该版本, 请键入: /help intro
jshell>
来吧,玩一下jshell。
jshell> System.out.println("Hello Java9")
Hello Java9
jshell> "abc".matches("a[bc]{2}")
$2 ==> true
jshell> IntStream.iterate(1, i -> i < 10, i -> i + 1).forEach(System.out::println)
1
2
3
4
5
6
7
8
9
哈哈,是不是有了一点Python的感觉。
JDK9将Jshell相关API封装为模块方便使用。下面我们通过代码来学习一下相关的API:
import java.io.ByteArrayInputStream;
import java.io.Console;
import java.util.List;
import jdk.jshell.*;
import jdk.jshell.Snippet.Status;
/**
Jshell
**/
public class JshellMain {
public static void main(String[] args) {
Console console = System.console();
//创建一个Jshell环境,之后会自动进行关闭
try (JShell js = JShell.create()) {
//循环监听输出
do {
System.out.print("请输入一些Java代码: ");
String input = console.readLine();
if (input == null) {
break;
}
//将输入的指令转化为SnippetEvent对象
List<SnippetEvent> events = js.eval(input);
for (SnippetEvent e : events) {
StringBuilder sb = new StringBuilder();
if (e.causeSnippet() == null) {
// 我们有一个片段创建的事件
switch (e.status()) {//根据代码片段的执行进行输出
case VALID:
sb.append("Successful ");
break;
case RECOVERABLE_DEFINED:
sb.append("With unresolved references ");
break;
case RECOVERABLE_NOT_DEFINED:
sb.append("Possibly reparable, failed ");
break;
case REJECTED:
sb.append("Failed ");
break;
}
if (e.previousStatus() == Status.NONEXISTENT) {
sb.append("addition");
} else {
sb.append("modification");
}
sb.append(" of ");
sb.append(e.snippet().source());
System.out.println(sb);
if (e.value() != null) {
System.out.printf("Value is: %s\n", e.value());
}
System.out.flush();
}
}
} while (true);
}
System.out.println("\nGoodbye");
}
}
编译执行命令如下:
javac JshellMain.java -encoding UTF-8
java JshellMain
执行结果如下:
请输入一些Java代码: 1+1
Successful addition of 1+1
Value is: 2
请输入一些Java代码: 3*2
Successful addition of 3*2
Value is: 6
请输入一些Java代码: 1>2
Successful addition of 1>2
Value is: false
请输入一些Java代码: for(int i = 0;i<10;i<10){System.out.println(i);}
Failed addition of for(int i = 0;i<10;i<10){System.out.println(i);}
请输入一些Java代码: for(int i = 0;i<10;i++){System.out.println(i);}
0
1
2
3
4
5
6
7
8
9
Successful addition of for(int i = 0;i<10;i++){System.out.println(i);}
Value is:
二.HTTP 2.0 客户端
Java9全面支持HTTP2.0,客户端实现完全更新。大家可能不了解HTTP2.0,GRPC就是2.0的模型,比1.0(包括1.0,1.1)好在哪里?2.0采用二进制格式,而1.0是文本格式。2.0完全是多路复用,一个连接可以实现并行;2.0报头压缩,降低了开销。另外,一个很重要的点就是,1.0只有pull,2.0是可以server push到client的。编程模型发生变化,可玩的空间大了很多,JDK原生支持,完美!
HTTP2.0相对 HTTP 1.1 有巨大的速度提升,范围在 11.81% 到 47.7% 之间,并且它已经存在于大多 数现代的浏览器中了。 Java 9 全面支持 HTTP 2.0 ,并且为 Java 配备一个全新的 HTTP 客户 端来替代 HttpURLConnection ,并且同时还实现 HTTP 2.0 和 websocket。
三.模块
也就是Jigsaw项目,这应该是最大的变动吧。它的主要目标就是模块化JVM,包括JDK、Java源代码等等,这个原生的支持,也不需要羡慕了,大概是这个样子:
module Java9 {
exports;
requires;
}
模块化的JAR文件,包含一个额外的模块描述符。requires表示依赖其他模块,exports控制哪些包可以被其他模块访问。是不是有些眼熟,那就对了!期待在实践中发挥巨大的作用。
四.改进的进程API
模块化的JAR文件,包含一个额外的模块描述符。requires表示依赖其他模块,exports控制哪些包可以被其他模块访问。是不是有些眼熟,那就对了!期待在实践中发挥巨大的作用。
- java.lang.ProcessHandle
- java.lang.ProcessHandle.info
包含功能:新的定位方法用户处理PID、进程名称和状态,并且可以方便的枚举进程。
一个特别有用的:
jshell> System.out.println(" PID is " + ProcessHandle.current())
PID is 68479
jshell>
五.轻量级的JSON API
java9终于内置了一个轻量级的JSON API,终于可以使用Java内置的API来生成JSON文件和资料流,而不用像过去得靠外挂JSON。
这版本JSON API的目标有:
1.解析和生成 JSON。
2.满足 Java 开发者使用 JSON 的功能性需求。
3.解析 API 可以选择标记流,事件(包括文件层次结构)流,或不可变树的方式来呈现文档或数据流视图。
4.用于紧凑配置和 Java ME 的 API 子集。
5.使用创建者模式 API 构造不可变的树型结构。
6.生成器风格 API,用于输出 JSON 数组流和 JSON “文本”。
7.一个转换 API,将已有的树形值输入转换成另一个树形值输出。
六.接口私有方法
Java8接口可以有默认方法和静态方法,但不能有私有方法,为了进一步提高可重用性,现在可以有private的方法了。
public interface Bird {
private void fly() {
// your code here
}
}
七.响应式流编程
新的API:java.util.concurrent.Flow,封装以下四个接口:
1.Flow.Processor
2.Flow.Publisher
3.Flow.Subscriber
4.Flow.Subscription
很滑,支持响应流的发布订阅框架,代码体验提升,更加清晰。
八.Linking
根据我们之前将的模块系统,新的好玩的特性来了。根据模块的划分,我们可以创建一个最小的运行时环境,只包含所需的模块。这个,就是通过jlink工具来实现的。这样,谁在诟病Java运行包太重?
九.集合工厂方法
这个比较方便,熟悉Guava的同学,相信早就知道用的飞起。Java9迟迟加入进来,当然也是不晚的。
jshell> Set<Integer> ints = Set.of(1,2,3)
ints ==> [1, 2, 3]
jshell> List<String> strings = List.of("java8", "java9")
strings ==> [java8, java9]
十.Stream API改进
Stream API也有相应的改进,在Java9中,确实变得更加的好。Stream接口中新增4个方法:
dopWhile
takeWhile
ofNullable
iterate以及其重载方法
来个小例子:
jshell> IntStream.iterate(1, i -> i < 10, i -> i + 1).forEach(System.out::println);
1
2
3
4
5
6
7
8
9
另外,一个很有用的点:
jshell> Stream<Integer> s = Optional.of(1).stream();
s ==> java.util.stream.ReferencePipeline$Head@2286778
上面讲了一些新特性,仍有很多,尤其是一些API改进的细节,靠大家自己玩耍了。