Java9|Java10|Java11新特性

Java9的新特性

JDK 9 的发布

  • 经过4次跳票,历经曲折的Java 9 终于终于在2017年9月21日发布。
  • 从Java 9 这个版本开始,Java 的计划发布周期是 6 个月,下一个 Java 的主版本将于 2018 年 3 月发布,命名为 Java 18.3,紧接着再过六个月将发布 Java18.9
  • 这意味着Java的更新从传统的以特性驱动的发布周期,转变为以时间驱动的(6 个月为周期)发布模式,并逐步的将 Oracle JDK 原商业特性进行开源。
  • 针对企业客户的需求,Oracle 将以三年为周期发布长期支持版本(long termsupport)。
  • Java 9 提供了超过150项新功能特性,包括备受期待的模块化系统、可交互的 REPL 工具:jshell,JDK 编译工具,Java 公共 API 和私有代码,以及安全增强、扩展提升、性能管理改善等。可以说Java 9是一个庞大的系统工程,完全做了一个整体改变。

  • 模块化系统
  • jShell命令
  • 多版本兼容jar包
  • 接口的私有方法
  • 语法改进:钻石操作符的使用升级
  • 语法改进:try语句
  • String存储结构变更
  • 集合工厂方法:快速创建只读集合-便利的集合特性:of()
  • 增强的Stream API
  • 全新的HTTP客户端API
  • Deprecated的相关API
  • javadoc的HTML 5支持
  • Javascript引擎升级:Nashorn
  • java的动态编译器

JDK 和 JRE 目录结构的改变

JDK8的目录结构
在这里插入图片描述
JDK 9 的目录结构
在这里插入图片描述

模块化系统: Jigsaw -> Modularity

  • 谈到 Java 9 大家往往第一个想到的就是 Jigsaw 项目。众所周知,Java 已经
    发展超过 20 年(95 年最初发布),Java 和相关生态在不断丰富的同时也越
    来越暴露出一些问题:

    • Java 运行环境的膨胀和臃肿。每次JVM启动的时候,至少会有30~60MB的内存
      加载,主要原因是JVM需要加载rt.jar,不管其中的类是否被classloader加载,第
      一步整个jar都会被JVM加载到内存当中去(而模块化可以根据模块的需要加载程
      序运行需要的class)
    • **当代码库越来越大,创建复杂,盘根错节的“意大利面条式代码”的几率呈指数级的
      增长。**不同版本的类库交叉依赖导致让人头疼的问题,这些都阻碍了 Java 开发和
      运行效率的提升。
    • 很难真正地对代码进行封装, 而系统并没有对不同部分(也就是 JAR 文件)之间
      的依赖关系有个明确的概念。每一个公共类都可以被类路径之下任何其它的公共
      类所访问到,这样就会导致无意中使用了并不想被公开访问的 API。
  • 本质上讲也就是说,用模块来管理各个package,通过声明某个package暴露,模块(module)的概念,其实就是package外再裹一层,不声明默认就是隐藏。因此,模块化使得代码组织上更安全,因为它可以指定哪些部分可以暴露,哪些部分隐藏

  • 实现目标

    • 模块化的主要目的在于减少内存的开销
    • 只须必要模块,而非全部jdk模块,可简化各种类库和大型应用的开发和维护
    • 改进 Java SE 平台,使其可以适应不同大小的计算设备
    • 改进其安全性,可维护性,提高性能

模块将由通常的类和新的模块声明文件(module-info.java)组成。该文件是位于java代码结构的顶层,该模块描述符明确地定义了我们的模块需要什么依赖关系,以及哪些模块被外部使用。在exports子句中未提及的所有包默认情况下将封装在模块中,不能在外部使用。
在这里插入图片描述
要想在java9demo模块中调用java9test模块下包中的结构,需要在java9test的module-info.java中声明:

module java9test {
	//package we export
	exports com.atguigui.bean;
}

exports:控制着哪些包可以被其它模块访问到。所有不被导出的包默认都被封装在模块里面。


对应在java 9demo 模块的src 下创建module-info.java文件:

module java9demo {
	requires java9test;
}

requires:指明对其它模块的依赖。

Java的REPL工具: jShell命令

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

接口的私有方法

Java 8中规定接口中的方法除了抽象方法之外,还可以定义静态方法和默认的方法。一定程度上,扩展了接口的功能,此时的接口更像是一个抽象类。
在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)在Java 8中如下的操作是会报错的:

Comparator<Object> com = new Comparator<>(){
	@Override
	public int compare(Object o1, Object o2) {
		return 0;
	}
};

编译报错信息:Cannot use “<>” with anonymous inner classes.

Java 9中如下操作可以正常执行通过:

// anonymous classes can now use type inference
Comparator<Object> com = new Comparator<>(){
	@Override
	public int compare(Object o1, Object o2) {
		return 0;
	}
};

语法改进:try语句

Java 8 中,可以实现资源的自动关闭,但是要求执行后必须关闭的所有资源必须在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();
}

String存储结构变更

在这里插入图片描述
在这里插入图片描述

集合工厂方法:快速创建只读集合-便利的集合特性:of()

要创建一个只读、不可改变的集合,必须构造和分配它,然后添加元素,最后包装成一个不可修改的集合。

List<String> namesList = new ArrayList <>();
namesList.add("Joe");
namesList.add("Bob");
namesList.add("Bill");
namesList = Collections.unmodifiableList(namesList);
System.out.println(namesList);

缺点:我们一下写了五行。即:它不能表达为单个表达式。

List<String> list = Collections.unmodifiableList(Arrays.asList("a", "b", "c"));
Set<String> set = Collections.unmodifiableSet(new HashSet<>(Arrays.asList("a","b", "c")));
// 如下操作不适用于jdk 8 及之前版本,适用于jdk 9
Map<String, Integer> map = Collections.unmodifiableMap(new HashMap<>() {
{
	put("a", 1);
	put("b", 2);
	put("c", 3);
}
});
map.forEach((k, v) -> System.out.println(k + ":" + v));

Java 9因此引入了方便的方法,这使得类似的事情更容易表达。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

增强的Stream API

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Java10的新特性

  • 2018年3月21日,Oracle官方宣布Java10正式发布。
  • 需要注意的是 Java 9 和 Java 10 都不是 LTS (Long-Term-Support) 版本。和过去的 Java 大版本升级不同,这两个只有半年左右的开发和维护期。而未来的 Java 11,也就是 18.9 LTS,才是 Java 8 之后第一个 LTS 版本。
  • JDK10一共定义了109个新特性,其中包含12个JEP(对于程序员来讲,真正的新特性其实就一个),还有一些新API和JVM规范以及JAVA语言规范上的改动。
  • JDK10的12个JEP(JDK Enhancement Proposal特性加强提议)参阅官方文档:http://openjdk.java.net/projects/jdk/10/

在这里插入图片描述

局部变量类型推断

  • 产生背景
    开发者经常抱怨Java中引用代码的程度。局部变量的显示类型声明,常常被认为是不必须的,给一个好听的名字经常可以很清楚的表达出下面应该怎样继续。
  • 好处:
    减少了啰嗦和形式的代码,避免了信息冗余,而且对齐了变量名,更容易阅读!
  • 举例如下:
    • 场景一:类实例化时
      作为 Java开发者,在声明一个变量时,我们总是习惯了敲打两次变量类型,第一次用于声明变量类型,第二次用于构造器。
      LinkedHashSet<Integer> set = new LinkedHashSet<>();

    • 场景二:返回值类型含复杂泛型结构
      变量的声明类型书写复杂且较长,尤其是加上泛型的使用
      Iterator<Map.Entry<Integer, Student>> iterator = set.iterator();

    • 场景三:
      我们也经常声明一种变量,它只会被使用一次,而且是用在下一行代码中,比如:

URL url = new URL("http://www.atguigu.com");
URLConnection connection = url.openConnection();
Reader reader = new BufferedReader(new
InputStreamReader(connection.getInputStream()));

适用于以下情况:

//1.局部变量的初始化
var list = new ArrayList<>();
//2.增强for循环中的索引
for(var v : list) {
	System.out.println(v);
}
//3.传统for循环中
for(var i = 0;i < 100;i++) {
	System.out.println(i);
}

在这里插入图片描述
不适用以下的结构中:

  • 情况1:没有初始化的局部变量声明
  • 情况2:方法的返回类型
  • 情况3:方法的参数类型
  • 情况4:构造器的参数类型
  • 情况5:属性
  • 情况6:catch块

在这里插入图片描述
在这里插入图片描述

集合新增创建不可变集合的方法

自 Java 9 开始,Jdk 里面为集合(List / Set / Map)都添加了 of(jdk9新增)和copyOf(jdk10新增)方法,它们两个都用来创建不可变的集合,来看下它们的使用和区别。

//示例1:
var list1 = List.of("Java", "Python", "C");
var copy1 = List.copyOf(list1);
System.out.println(list1 == copy1); // true
//示例2:
var list2 = new ArrayList<String>();
var copy2 = List.copyOf(list2);
System.out.println(list2 == copy2); // false
//示例1和2代码基本一致,为什么一个为true,一个为false?

从 源 码 分 析 , 可 以 看 出 copyOf方 法 会 先 判 断 来 源 集 合 是 不 是AbstractImmutableList 类型的,如果是,就直接返回,如果不是,则调用 of 创建一个新的集合。

示例2因为用的 new 创建的集合,不属于不可变 AbstractImmutableList 类的子类,所以 copyOf 方法又创建了一个新的实例,所以为false。

注意:使用of和copyOf创建的集合为不可变集合,不能进行添加、删除、替换、排序等操作,不然会报 java.lang.UnsupportedOperationException 异常。

上面演示了 List 的 of 和 copyOf 方法,Set 和 Map 接口都有。

Java11的新特性

北京时间 2018年9 月 26 日,Oracle 官方宣布 Java 11 正式发布。这是 Java 大版本周期变化后的第一个长期支持版本,非常值得关注。从官网即可下载,最新发布的 Java11 将带来 ZGC、Http Client 等重要特性,一共包含 17 个 JEP(JDK Enhancement Proposals,JDK 增强提案)。其实,总共更新不止17个,只是我们更关注如下的17个JEP更新。
在这里插入图片描述

JDK 11 是一个长期支持版本(LTS, Long-Term-Support)

  • 对于企业来说,选择 11 将意味着长期的、可靠的、可预测的技术路线图。其中免费的OpenJDK11 确定将得到 OpenJDK 社区的长期支持, LTS 版本将是可以放心选择的版本。
  • 从 JVM GC 的角度,JDK11 引入了两种新的 GC,其中包括也许是划时代意义的 ZGC,虽然其目前还是实验特性,但是从能力上来看,这是 JDK 的一个巨大突破,为特定生产环境的苛刻需求提供了一个可能的选择。例如,对部分企业核心存储等产品,如果能够保证不超过 10ms 的 GC 暂停,可靠性会上一个大的台阶,这是过去我们进行 GC 调优几乎做不到的,是能与不能的问题。
    在这里插入图片描述
    在这里插入图片描述
    官网公开的 17 个 JEP(JDK Enhancement Proposal 特性增强提议)

181: Nest-Based Access Control(基于嵌套的访问控制)
309: Dynamic Class-File Constants(动态的类文件常量)
315: Improve Aarch64 Intrinsics(改进 Aarch64 Intrinsics)
318: Epsilon: A No-Op Garbage Collector(Epsilon 垃圾回收器,又被称为"No-Op(无操作)"回收器)
320: Remove the Java EE and CORBA Modules(移除 Java EE 和 CORBA 模块,JavaFX也已被移除)
321: HTTP Client (Standard)
323: Local-Variable Syntax for Lambda Parameters(用于 Lambda 参数的局部变量语法)
324: Key Agreement with Curve25519 and Curve448(采用 Curve25519 和 Curve448 算法实现的密钥协议)
327: Unicode 10
328: Flight Recorder(飞行记录仪)
329: ChaCha20 and Poly1305 Cryptographic Algorithms(实现 ChaCha20 和 Poly1305 加密算法)
330: Launch Single-File Source-Code Programs(启动单个 Java 源代码文件的程序)
331: Low-Overhead Heap Profiling(低开销的堆分配采样方法)
332: Transport Layer Security (TLS) 1.3(对 TLS 1.3 的支持)
333: ZGC: A Scalable Low-Latency Garbage Collector (Experimental)(ZGC:可伸缩的低延迟垃圾回收器,处于实验性阶段)
335: Deprecate the Nashorn JavaScript Engine(弃用 Nashorn JavaScript 引擎)
336: Deprecate the Pack200 Tools and API(弃用 Pack200 工具及其 API)

新增了一系列字符串处理方法

在这里插入图片描述

Optional 加强

Optional 也增加了几个非常酷的方法,现在可以很方便的将一个 Optional 转换
成一个 Stream, 或者当一个空 Optional 时给它一个替代的。
在这里插入图片描述

局部变量类型推断升级

在var上添加注解的语法格式,在jdk10中是不能实现的。在JDK11中加入了这样
的语法。

//错误的形式: 必须要有类型, 可以加上var
//Consumer<String> con1 = (@Deprecated t) ->
System.out.println(t.toUpperCase());
//正确的形式:
//使用var的好处是在使用lambda表达式时给参数加上注解。
Consumer<String> con2 = (@Deprecated var t) ->
System.out.println(t.toUpperCase());

全新的HTTP 客户端API

在这里插入图片描述
在这里插入图片描述

更简化的编译运行程序

在这里插入图片描述

废弃Nashorn引擎

废除Nashorn javascript引擎,在后续版本准备移除掉,有需要的
可以考虑使用GraalVM。

ZGC

  • GC是java主要优势之一。 然而, 当GC停顿太长, 就会开始影响应用的响应时间。消除或者减少GC停顿时长, java将对更广泛的应用场景是一个更有吸引力的平台。此外, 现代系统中可用内存不断增长,用户和程序员希望JVM能够以高效的方式充分利用这些内存, 并且无需长时间的GC暂停时间。
  • ZGC, A Scalable Low-Latency Garbage Collector(Experimental)ZGC, 这应该是JDK11最为瞩目的特性, 没有之一。 但是后面带了Experimental,说明这还不建议用到生产环境。
  • ZGC是一个并发, 基于region, 压缩型的垃圾收集器, 只有root扫描阶段会STW(stop the world), 因此GC停顿时间不会随着堆的增长和存活对象的增长而变长。
  • 优势:
    • GC暂停时间不会超过10ms
    • 既能处理几百兆的小堆, 也能处理几个T的大堆(OMG)
    • 和G1相比, 应用吞吐能力不会下降超过15%
    • 为未来的GC功能和利用colord指针以及Load barriers优化奠定基础
    • 初始只支持64位系统
  • ZGC的设计目标是:支持TB级内存容量,暂停时间低(<10ms),对整个
    程序吞吐量的影响小于15%。 将来还可以扩展实现机制,以支持不少令人
    兴奋的功能,例如多层堆(即热对象置于DRAM和冷对象置于NVMe闪存),
    或压缩堆。

其它新特性

  • Unicode 10
  • Deprecate the Pack200 Tools and API
  • 新的Epsilon垃圾收集器
  • 完全支持Linux容器(包括Docker)
  • 支持G1上的并行完全垃圾收集
  • 最新的HTTPS安全协议TLS 1.3
  • Java Flight Recorder
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值