Java 9

提到Java 8则必须知道的新特性莫过于Lambda表达式和Stream API。经过三年多的时间后,Java 9于2017年9月21日正式Release。此次更新也是具有革命性的,共计超过150多项功能更新。归结起来,最重大的更新莫过于:模块化系统和jShell命令。
值得注意的是,从Java9开始,Java的计划发布周期为6个月,或者更短的时间。这是我之前总结的文章,由于公司内的网络不能上传所有文件,所以,一直没来得及生成博客。
截止到目前, 我去官网看了下Java已经出了Java 11。
https://www.oracle.com/technetwork/java/javase/downloads/index.html

在此需要重点说明的Java 9的新特性大概有18个。

一、模块化系统

旧版本面临的问题:

  1. Java 运行环境的膨胀和臃肿。主要原因是JVM需要加载rt.jar,不管其中的类是否被classloader加载,第一步整个jar都会被JVM加载到内存当中去(而模块化可以根据模块的需要加载程序运行需要的class)。
  2. 代码库越来越大,类库交叉依赖错综复杂。
  3. 依赖的很少,加载的很多。每一个公共类类都可以被类路径之下任何其它的公共类所访问到,这样就会导致无意中使用了并不想被公开访问的API。除此之外,还有许多原因,不一一细说。

新功能的设计理念:模块独立,化繁为简

新功能的目的:较少内存开销、简化类库、改进Java SE适应不同设备、改进安全性。
使用:
模块的 src 下创建 module-info.java 文件,在该文件中编写暴露的接口和需要引入模块。

二、jShell—Java的REPL工具

产生背景:
Read Eval Print Loop:交互式解释器
在Java没有引入函数式编程之前,对Java语言冲击最大的莫过于Python和Scala(Spark内核就是用Scala语言编写的),而这两种语言(甚至更多的语言)都是支持REPL工具的。所以,Java不仅仅加入了其他语言的新特性,也加入了自己独有的REPL工具——jShell。

设计理念与目的: 即写即得、快速运行

Java 9_第1张图片
Java 9_第2张图片
默认已经导入的包:
Java 9_第3张图片
按Tab键,自动补全:
Java 9_第4张图片
罗列出当前窗口(会话)的有效代码:
Java 9_第5张图片
查看此会话中声明的所有变量和方法:
在这里插入图片描述
在这里插入图片描述
还有更多的功能和操作,可以查看相关资料。

三、多版本兼容jar

产生背景:
在老项目中要用一些新特性时,就需要考虑Java版本升级的问题,但是这样做太浪费时间、精力和资源,Java9就提供了对多版本的支持。
设计理念和目的:项目可以采用多个Java版本开发。

四、语法改进: 接口的私有方法

产生背景:java8引入(函数式编程思想)Lambda后,规定接口中的方法除了抽象方法之外,还可以定义静态方法和默认的方法。一定程度上,扩展了接口的功能,此时的接口更像是一个抽象类。
在 Java 9 中,接口更加的灵活和强大,连方法的访问权限修饰符都可以声明为 private 的了,此时方法将不会成为你对外暴露的 API的一部分。

interface MyInterface {
	
	void normalInterfaceMethod();

	default void methodDefault1() {
		init();
	}

	public default void methodDefault2() {
		init();
	}

	// This method is not part of the public API exposed by MyInterface
	private void init() {
		System.out.println(" 默认方法中的通用操作");
	}
}

class MyInterfaceImpl implements MyInterface {
	
	@Override
	public void normalInterfaceMethod() {
		System.out.println(" 实现接口的方法");
	}
}
public class MyInterfaceTest {
	public static void main(String[] args) {
		MyInterfaceImpl impl = new MyInterfaceImpl();
		impl.methodDefault1();
		// impl.init();// 不能调用
	}
}
五、语法改进:Diamond Operator

产生背景:关于该特性,主要是对钻石操作符号进行了升级使用。

我们将能够与匿名实现类共同使用钻石操作符,如果是在Java8中,则如下代码会报错:

private List flattenStrings(List... lists) {
	Set set = new HashSet<>(){};
	for(List list : lists) {
		set.addAll(list);
	}
	return new ArrayList<>(set);
}
编译报错信息: '<>' cannot be used with anonymous classes

但是,Java9进行了升级:

private List flattenStrings(List... lists) {
	// anonymous classes can now use type inference
	Set set = new HashSet<>(){};
	for(List list : lists) {
		set.addAll(list);
	}
	return new ArrayList<>(set);
}
六、语法改进:try语句

产生背景:简化语法
设计理念和目的:对try语句进行简化。

Java8之前:

InputStreamReader reader = null;
try{
	reader = new InputStreamReader(System.in);
	// 流的操作
	reader.read();
}catch (IOException e){
	e.printStackTrace();
}finally{
	if(reader != null){
		try {
			reader.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

Java8中已经有了一点改进,可以实现资源的自动关闭,但是要求执行后必须关闭的所有资源必须在 try 子句中初始化,否则编译不通过。如下例所示:

try(InputStreamReader reader = new
	InputStreamReader(System.in)){
}catch (IOException e){
	e.printStackTrace();
}

java 9 中,用资源语句编写 try 将更容易,我们可以在 try 子句中使用已经初始化过的资源,此时的资源是 final 的:

InputStreamReader reader = new InputStreamReader(System.in);
OutputStreamWriter writer = new OutputStreamWriter(System.out);
try(reader;writer){
	//reader 是 final 的,不可再被赋值
	// reader = null;
}catch (IOException e){
	e.printStackTrace();
}
七、语法改进:UnderScore( 下划线) 使用的限制

产生背景:规范代码
设计理念和目的:规范代码
在 java 8 中,标识符可以独立使用“ _ ” 来命名,但是,在 java 9 中规定“_”不再可以单独命名标识符了,如果使用则会报错。

八、String存储结构变更

产生背景:节省空间资源
设计理念和目的:String 再也不用 char[] 来存储啦,改成了 byte[] 加上编码标记,节约了一些空间。

九、集合工厂方法:快速创建只读集合

产生背景:要创建一个只读、不可改变的集合,必须构造和分配它,然后添加元素,最后包装成一个不可修改的集合。这样就有点麻烦。
设计理念和目的:简化操作和开发。

调用集合中静态方法 of(),可以将不同数量的参数传输到此工厂方法中。此功能可用于 Set 和 List,也可用于 Map 的类似形式。此时得到的集合,是不可变的:在创建后,继续添加元素到这些集合会导致“UnsupportedOperationException” 。

十、增强的Stream API

产生背景:Java 的 Steam API 是java标准库最好的改进之一,让开发者能够快速运算,从而能够有效的利用数据并行计算。Java 8 提供的 Steam能够利用多核架构实现声明式的数据处理。

在 Java 9 中,Stream API 变得更好,Stream 接口中添加了 4 个新的方法:dropWhile, takeWhile, ofNullable,还有个 iterate 方法的新重载方法,可以让你提供一个 Predicate (判断条件)来指定什么时候结束迭代。

除了对 Stream 本身的扩展,Optional 和 Stream 之间的结合也得到了改进。现在可以通过 Optional 的新方法 stream() 将一个Optional 对象转换为一个(可能是空的) Stream 对象。

十一、多分辨率图像

产生背景:Mac 上,JDK 已经支持视网膜显示,但在 Linux 和 Windows 上,它并没有。此次更新便弥补了此缺憾。
设计理念、目的说明:使用比现在更多的现代 API:Direct2D for Windows和 GTK +,而不是 Xlib for Linux。图形,窗口和文本由此自动缩放。JEP 251 还提供处理多分辨率图像的能力,即包含不同分辨率的相同图像的文件。根据相应屏幕的 DPI 度量,然后以适当的分辨率使用图像。

个人感觉此项功能用的还是比较少的。

十二、全新的HTTP客户端API

产生背景:
HTTP/1.1和HTTP/2的主要区别是如何在客户端和服务器之间构建和传输数据。HTTP/1.1 依赖于请求/响应周期。 HTTP/2 允许服务器“push”数据:它可以发送比客户端请求更多的数据。 这使得它可以优先处理并发送对于首先加载网页至关重要的数据。

设计理念和目的:
Java 9 中有新的方式来处理 HTTP 调用。它提供了一个新的 HTTP客 户 端 ( HttpClient), 它 将 替 代 仅 适 用 于 blocking 模式的HttpURLConnection (HttpURLConnection是在HTTP 1.0的时代创建的,并使用了协议无关的方法),并提供对 WebSocket 和 HTTP/2 的支持。此外,HTTP 客户端还提供 API 来处理 HTTP/2 的特性,比如流和服务器推送等功能。

全新的 HTTP 客户端 API 可以从 jdk.incubator.httpclient 模块中获取。因为在默认情况下,这个模块是不能根据 classpath 获取的,需要使用 add modules 命令选项配置这个模块,将这个模块添加到 classpath中。

HttpClient client = HttpClient.newHttpClient();

HttpRequest req =HttpRequest.newBuilder(URI.create("http://www.atguigu.com")).GET().build();

HttpResponse response = client.send(req,HttpResponse.BodyHandler.asString());

System.out.println(response.statusCode());
System.out.println(response.version().name());
System.out.println(response.body());
十三、废弃不常用的API

产生背景:有许多API从java诞生起,就很少被人使用。

Java 9 废弃或者移除了几个不常用的功能。其中最主要的是Applet API,现在是标记为废弃的。随着对安全要求的提高,主流浏览器已经取消对 Java 浏览器插件的支持。HTML5 的出现也进一步加速了它的消亡。开发者现在可以使用像 Java Web Start 这样的技术来代替 Applet,它可以实现从浏览器启动应用程序或者安装应用程序。

同时,appletviewer 工具也被标记为废弃。

十四、智能Java编译工具

在之前我们一直使用的都是javac,此次java9推出了智能 java 编译工具( sjavac ),sjavac的第一个阶段始于 JEP139 这个项目,用于在多核处理器情况下提升 JDK 的编译速度。如今,这个项目已经进入第二阶段,即 JEP199,其目的是改进 Java 编译工具,并取代目前 JDK 编译工具 javac,继而成为 Java 环境默认的通用的智能编译工具。

JDK 9 还更新了 javac 编译器以便能够将 java 9 代码编译运行在低版本 Java 中。

十五、JVM日志系统

产生背景:
日志是解决问题的唯一有效途径:曾经很难知道导致 JVM 性能问题和导致 JVM 崩溃的根本原因。不同的 JVM 日志的碎片化和日志选项(例如:JVM 组件对于日志使用的是不同的机制和规则),这使得 JVM 难以进行调试。

设计理念和目的:
解决该问题最佳方法:对所有的 JVM 组件引入一个单一的系统,这些 JVM 组件支持细粒度的和易配置的 JVM 日志。

十六、Javadoc的HTML5支持

产生背景:旧版本的java帮组文档是在HTML4中,现在符合HTML5标准
Java 9_第6张图片

十七、Javascript引擎升级:Nashorn

产生背景:
需要为java提供轻量级的JavaScript运行时环境,来整合JavaScript,并提高效率。

Nashorn 项目跟随 Netscape 的 Rhino 项目,目的是为了在 Java 中实现一个高性能但轻量级的 Javascript 运行时。Nashorn 项目使得 Java 应用能够嵌入 Javascript。它在 JDK 8 中为
Java 提供一个 Javascript 引擎。

JDK 9 包含一个用来解析 Nashorn 的 ECMAScript 语法树的API。这个 API 使得 IDE 和服务端框架不需要依赖 Nashorn 项目的内部实现类,就能够分析 ECMAScript 代码。

十八、java的动态编译器

产生背景:
Oracle 一直在努力提高 Java 启动和运行时性能,希望其能够在更广泛的场景达到或接近本地语言的性能。但是,直到今天,谈到Java,很多 C/C++ 开发者还是会不屑地评价为启动慢,吃内存。
简单说,这主要是因为 Java 编译产生的类文件是 Java 虚拟机可以理解的二进制代码,而不是真正的可执行的本地代码,需要 Java虚拟机进行解释和编译,这带来了额外的开销。

使用说明:
JIT(Just-in-time)编译器可以在运行时将热点编译成本地代码,速度很快。但是 Java 项目现在变得很大很复杂,因此 JIT 编译器需要花费较长时间才能热身完,而且有些 Java 方法还没法编译,性能方面也会下降。AoT 编译就是为了解决这些问题而生的。

在 JDK 9 中, AOT(JEP 295: Ahead-of-Time Compilation)作为实验特性被引入进来,开发者可以利用新的 jaotc 工具将重点代码转换成类似类库一样的文件。虽然仍处于试验阶段,但这个功能使得 Java应用在被虚拟机启动之前能够先将 Java 类编译为原生代码。此功能旨在改进小型和大型应用程序的启动时间,同时对峰值性能的影响很小。
目前的稳定版本就是Java 11。

后语:
这篇文章是很早之前写的,现在才放到博客上(公司的网络不允许上传各种文件所限),回望2018年互联网技术界,最火的莫过于人工智能、微服务(SpringCloud/SpringBoot/Dubbo/Zookeeper/Redis/Mycat等)、云平台。当前的计算模式和场景正在发生翻天覆地的变化,不仅对 Java 的发展速度提出了更高要求,也深刻影响着 Java 技术的发展方向。传统的大型企业或互联网应用,正在被云端、容器化应用、模块化的微服务甚至是函数(FaaS,Function-as-a-Service) 所替代。
虽然,Java是面向对象编程的,但随着技术的演进,又不断引进了其他语言的各种独有特性,比如面向函数/过程编程,可以说,每当引入一个新的特性时,都是对Java的本质思想的一次冲击。如果可以,我们作为一名程序员或者说是技术者,要时刻关注前沿科技和发展趋势才行,必须要多掌握热门语言才行!

你可能感兴趣的:(Java,EE,Java,9,Java9,新特性)