java9&java10&java11新特性介绍

1. java9新特性

Java 9 提供了超过150项新功能特性,包括备受期待的模块化系统、可交互的 REPL 工具:jshell,JDK 编译工具,Java 公共 API 和私有代码,以及安全增强、扩展提升、性能管理改善等。可以说Java 9是一个庞大的系统工程,完全做了一个整体改变。
一些重要的新特性如下:
在这里插入图片描述
模块化系统
谈到 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外再裹一层,不声明默认就是隐藏。因此,模块化使得代码组织上更安全,因为它可以指定哪些部分可以暴露,哪些部分隐藏。
模块化系统的使用
在这里插入图片描述
要想在java9demo模块中调用java9test模块下包中的结构,需要在java9test的module-info.java中声明:

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

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

module java9demo {
requires java9test;
}

jShell命令
像Python 和 Scala 之类的语言早就有交互式编程环境 REPL (read - evaluate - print -loop)了,以交互式的方式对语句和表达式进行求值。开发者只需要输入一些代码,就可以在编译前获得对程序的反馈。而之前的Java版本要想执行代码,必须创建文件、声明类、提供测试方法方可实现。

Java 9 中终于拥有了 REPL工具:jShell。让Java可以像脚本语言一样运行,从
控制台启动jShell,利用jShell在没有创建类的情况下直接声明变量,计算表达式,执行语句。即开发时可以在命令行里直接运行Java的代码,而无需创建Java文件,无需跟人解释”public static void main(String[] args)”这句废话。
栗子:
在这里插入图片描述
语法改进:接口的私有方法
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存储结构变更
String 再也不用 char[] 来存储啦,改成了 byte[] 加上编码标记,节约
了一些空间。

public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
@Stable
private final byte[] value;
}

并且StringBuffer和StringBuilder也跟着变化。
集合工厂方法:快速创建只读集合
java创建可读集合的方法:
在这里插入图片描述
List firsnamesList = List.of(“Joe”,”Bob”,”Bill”);
调用集合中静态方法of(),可以将不同数量的参数传输到此工厂方法中。此功能
可用于Set和List,也可用于Map的类似形式。此时得到的集合,是不可变的:在
创建后,继续添加元素到这些集合会导致 “UnsupportedOperationException” 。
由于Java 8中接口方法的实现,可以直接在List,Set和Map的接口内定义这些方法,便于调用。

InputStream 加强
InputStream 终于有了一个非常有用的方法:transferTo,可以用来将数据直接
传输到 OutputStream,这是在处理原始数据流时非常常见的一种用法,如下
示例。

ClassLoader cl = this.getClass().getClassLoader();
try (InputStream is = cl.getResourceAsStream("hello.txt");
OutputStream os = new FileOutputStream("src\\hello1.txt")) {
is.transferTo(os); // 把输入流中的所有数据直接自动地复制到输出流中
} catch (IOException e) {
e.printStackTrace();
}

增强的 Stream API

  1. takeWhile()的使用
    用于从 Stream 中获取一部分数据,接收一个 Predicate 来进行选择。在有序的
    Stream 中,takeWhile 返回从开头开始的尽量多的元素。
List<Integer> list = Arrays.asList(45, 43, 76, 87, 42, 77, 90, 73, 67, 88);
list.stream().takeWhile(x -> x < 50).forEach(System.out::println);
System.out.println();
list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8);
list.stream().takeWhile(x -> x < 5).forEach(System.out::println);
  1. dropWhile()的使用
    dropWhile 的行为与 takeWhile 相反,返回剩余的元素。
List<Integer> list = Arrays.asList(45, 43, 76, 87, 42, 77, 90, 73, 67, 88);
list.stream().dropWhile(x -> x < 50).forEach(System.out::println);
System.out.println();
list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8);
list.stream().dropWhile(x -> x < 5).forEach(System.out::println);
  1. ofNullable()的使用
    Java 8 中 Stream 不能完全为null,否则会报空指针异常。而 Java 9 中的 ofNullable 方法允许我们创建一个单元素 Stream,可以包含一个非空元素,也可以创建一个空Stream。
// 报NullPointerException
// Stream<Object> stream1 = Stream.of(null);
// System.out.println(stream1.count());
// 不报异常,允许通过
Stream<String> stringStream = Stream.of("AA", "BB", null);
System.out.println(stringStream.count());// 3
// 不报异常,允许通过
List<String> list = new ArrayList<>();
list.add("AA");
list.add(null);
System.out.println(list.stream().count());// 2
// ofNullable():允许值为null
Stream<Object> stream1 = Stream.ofNullable(null);
System.out.println(stream1.count());// 0
Stream<String> stream = Stream.ofNullable

iterate()重载的使用
这个 iterate 方法的新重载方法,可以让你提供一个 Predicate (判断条件)来指定什么时候结束迭代。

// 原来的控制终止方式:
Stream.iterate(1, i -> i + 1).limit(10).forEach(System.out::println);
// 现在的终止方式:
Stream.iterate(1, i -> i < 100, i -> i + 1).forEach(System.out::println);

Optional获取Stream的方法

List<String> list = new ArrayList<>();
list.add("Tom");
list.add("Jerry");
list.add("Tim");
Optional<List<String>> optional = Optional.ofNullable(list);
Stream<List<String>> stream = optional.stream();
stream.flatMap(x -> x.stream()).forEach(System.out::println);

2. java10新特性

局部变量类型推断
开发者经常抱怨Java中引用代码的程度。局部变量的显示类型声明,常常被认为是不必须的,给一个好听的名字经常可以很清楚的表达出下面应该怎样继续。
使用局部类型推断,减少了啰嗦和形式的代码,避免了信息冗余,而且对齐了变量名,更容易阅读!
适用于情况:

//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. 初始值为null
  2. 方法引用
  3. Lambda表达式
  4. 为数组静态初始化

不适用以下的结构中:
情况1:没有初始化的局部变量声明
情况2:方法的返回类型
情况3:方法的参数类型
情况4:构造器的参数类型
情况5:属性
情况6:catch块
工作原理
在处理 var时,编译器先是查看表达式右边部分,并根据右边变量值的类型进行
推断,作为左边变量的类型,然后将该类型写入字节码当中。
注意点:

  • var不是一个关键字
    你不需要担心变量名或方法名会与 var发生冲突,因为 var实际上并不是一个关键字,而是一个类型名,只有在编译器需要知道类型的地方才需要用到它。除此之外,它就是一个普通合法的标识符。也就是说,除了不能用它作为类名,其他的都可以,但极少人会用它作为类名。
  • 这不是JavaScript
    首先我要说明的是,var并不会改变Java是一门静态类型语言的事实。编译器负责推断出类型,并把结果写入字节码文件,就好像是开发人员自己敲入类型一样。
    集合新增创建不可变集合的方法
    自 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。

3. Java 11 新特性

JDK 11 是一个长期支持版本(LTS, Long-Term-Support)。
新增了一系列字符串处理方法
在这里插入图片描述
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
在这里插入图片描述
更简化的编译运行程序
看下面的代码。
// 编译
javac Javastack.java
// 运行
java Javastack
在我们的认知里面,要运行一个 Java 源代码必须先编译,再运行,两步执行动作。
而在未来的 Java 11 版本中,通过一个 java 命令就直接搞定了,如以下所示:
java Javastack.java
一个命令编译运行源代码的注意点:

  1. 执行源文件中的第一个类, 第一个类必须包含主方法。
  2. 并且不可以使用其它源文件中的自定义类, 本文件中的自定义类是可以使用的。

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停顿时间不会随着堆的增长和存活对象的增长而变长。

优势:

  1. GC暂停时间不会超过10ms
  2. 既能处理几百兆的小堆, 也能处理几个T的大堆(OMG)
  3. 和G1相比, 应用吞吐能力不会下降超过15%
  4. 为未来的GC功能和利用colord指针以及Load barriers优化奠定基础
  5. 初始只支持64位系统
  6. ZGC的设计目标是:支持TB级内存容量,暂停时间低(<10ms),对整个
    程序吞吐量的影响小于15%。 将来还可以扩展实现机制,以支持不少令人
    兴奋的功能,例如多层堆(即热对象置于DRAM和冷对象置于NVMe闪存),
    或压缩堆。
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值