JDK11特性

简介: 2018年9月26日,Oracle官方发布JAVA11。这是JAVA大版本周期变化后的第一个长期支持版本,非常值得关注。

@[TOC]

JAVA11 概述

2018年9月26日,Oracle官方发布JAVA11。这是JAVA大版本周期变化后的第一个长期支持版本,非常值得关注。最新发布的JAVA11将带来ZGC、HttpClient等重要特性,一共17个需要我们关注的JEP,参考文档http://openjdk.java.net/projects/jdk/11/

image.png

具体的特性介绍

  • 181:基于嵌套的访问控制
  • 309:动态类文件常量
  • 315:改进Aarch64 Intrinsics
  • 318:Epsilon:一个无操作的垃圾收集器
  • 320:移除Java EE和CORBA模块
  • 321:HTTP客户端(标准)
  • 323:本地变量语法Lambda参数
  • 324:与Curve25519和Curve448的密钥一致
  • 327: Unicode 10
  • 328:飞行记录器
  • 329: ChaCha20和Poly1305密码算法
  • 330:启动单文件源代码程序
  • 331:低开销堆分析
  • 332: TLS (Transport Layer Security) 1.3
  • 333:ZGC:一个可伸缩的低延迟垃圾收集器 (实验)
  • 335:已弃用Nashorn JavaScript引擎
  • 336:已弃用Pack200工具和API

语法层次的变化

局部变量类型推断升级

局部变量类型推断是java10开始新增的新特性,java11中对局部变量推断进行了升级,在var支持添加注解的语法格式,JAVA10中是无法实现的。

lambda表达式中,注解修饰变量的时候,变量的数据类型必须要写,不能省略,像下面这种写法就是错误的

Consumer<String> con =(@Deprecated  t) -> System.out.println(t.toLowerCase());

这个时候就必须要为小括号中的参数添加数据类型,应该这样写

Consumer<String> con =(@Deprecated String t) -> System.out.println(t.toLowerCase());

java11中,lambda表达式中的参数数据类型可以使用var,但是不能不写

Consumer<String> con =(@Deprecated var t) -> System.out.println(t.toLowerCase());

API层次的提升

String新增的方法

在JDK11中对String处理新增的很多方法。简化对字符串的操作

描述 举例
判断字符串是否为空白 " ".isBlank(); // true
去除字符串首尾空白 " www.boge.com ".strip(); // "www.boge.com"
去除字符串尾部空格 " www.boge.com ".stripTrailin(); // " www.boge.com"
去除字符串首部空格 " www.boge.com ".stripLeading(); // "www.boge.com "
复制字符串 "boge".repeat(2);// "bogeboge"
行数统计 "A\nB\nC\nD".lines().count(); // 4
    public static void main(String[] args) {
   
   
        // 判断字符串是否为空白
        boolean b = " ".isBlank();// true
        // 去除字符串首尾空白
        String s1 = " www.boge.com ".strip();// "www.boge.com"
        // 去除字符串尾部空格
        String s2 = " www.boge.com ".stripTrailing();// " \n \twww.boge.com"
        // 去除字符串首部空格
        String s3 = " www.boge.com ".stripLeading();// "www.boge.com\n \t "
        // 复制字符串
        String r = "boge".repeat(2);// "bogeboge"
        // 行数统计
        long c = "A\nB\nC\nD".lines().count();// 4
        System.out.println(s1);
        System.out.println(s2);
        System.out.println(s3);
        System.out.println(r);
        System.out.println(c);
    }

Optional新增方法

Optional也增加了几个非常好用的方法,现在可以很方便的把一个Optional转换成一个Stream,或者当一个空Optional时,给它一个替代的。我们发现从JDK8开始出现Stream以后,每个版本都有相关的更新.

新增方法 描述 新增版本
boolean isEmpty() 判断value是否为空 JDK11
T orElseThrow() value非空,返回value,否则抛出NoSuchElementExpception JDK10
ifPresentOrElse(Consumer<? super T> action,Runnable emptyAction) value非空,执行参数1功能,如果value为空,执行参数2功能 JDK9
Optional<T>or(Supplier<? extends Optional<? extends T> supplier) value非空,返回对应的Optional,value为空,返回形参封装的Optional JDK9
Stream<T>stream(); value非空,返回一个仅包含此value的Steam,否则,返回一个空的Stream JDK9
    public static void main(String[] args) {
   
   
        Optional<String> optional =Optional.empty();
        //JDK8 判断value是否存在
        System.out.println(optional.isPresent());
        //JDK11 判断value是否为空
        System.out.println(optional.isEmpty());

        //JDK10 返回value,如果为null则直接抛出 NoSuchElementExpception
        Optional<String> optional2 = Optional.of("element1");
        String value = optional2.orElseThrow();
        System.out.println(value);

        //JDK9  value非空,执行参数1功能,如果value为空,执行参数2功能
        Optional<String> optional3 =Optional.empty();// Optional.of("element1");
        optional.ifPresentOrElse((v)-> System.out.println("value为"+v),()-> System.out.println("value为null"));

        // JDK9 value非空,返回对应的Optional,value为空,返回形参封装的Optional
        Optional<String> optional4 =Optional.empty();// Optional.of("element1");
        Optional<String> optional5 = optional4.or(() -> Optional.of("element2"));
        System.out.println(optional5);

        // JDK9 value非空,返回一个仅包含此value的Steam,否则,返回一个空的Stream
        Optional<String> optional6 =Optional.of("element3");//Optional.empty();
        Stream<String> stream = optional6.stream();
        stream.forEach(System.out::println);
    }

HTTPClient

JAVA9开始引入一个处理HTTP请求的HTTPClient API,该API支持同步和异步,而在JAVA11中成为正式可用状态,可以在java.net包中找到这个API,它将替代仅适用于bolocking模式的HTTPUrlConnection(创建于Http1.0s时代,并使用了协议无关的方法),并提供对WebSocket和HTTP2的支持。

HttpClient 替换原有的HttpUrlConnection 同步方式


HttpClient client =HttpClient.newHttpClient();
HttpRequest request =HttpRequest.newBuilder(URI.create("http://127.0.0.1:8080/demo")).build();
HttpResponse.BodyHandler<String> respnoseBodyHandler= HttpResponse.BodyHandlers.ofString();
HttpResponse<String> response =client.send(request,respnoseBodyHandler);
String body = response.body();
System.out.println(body);

HttpClient 替换原有的HttpUrlConnection 异步方式

HttpClient client =HttpClient.newHttpClient();
HttpRequest request =HttpRequest.newBuilder(URI.create("http://127.0.0.1:8080/demo")).build();
HttpResponse.BodyHandler<String> respnoseBodyHandler= HttpResponse.BodyHandlers.ofString();
CompletableFuture<HttpResponse<String>> sendAsync = client.sendAsync(request, respnoseBodyHandler);
sendAsync.thenApply(t-> t.body()).thenAccept(System.out::println);

其他变化

更简化的编译运行

JAVA11之前编译一个java源代码文件语法应该是

javac Test1.java

解释执行一个java字节码的语法应该是

java Test1

而在java11中,通过一个java命令就可以直接搞定以上两件事,语法是:

java Test1.java

需要注意的是:

  1. 源代码文件中如果有多个类,执行源文件中的第一个类中主方法,注意这里的第一个是代码顺序的第一个,和是否由public修饰无关。
  2. 不可以使用其他源文件中定中自定义的类,当前文件中自定义的类是可以使用的。

定义一个源代码文件进行测试

public class HelloJAVA11{
   
   
    public static void main(String[] args){
   
   
        System.out.println("HelloJAVA11.main");
        // 实例化当前文件中的Person类
        Person p=new Person();
        // 实例化另一个文件中的Student类
        Student stu =new Student();

    }

}

class Person {
   
   
    private String pid;
    private String pname;

}
class Test2{
   
   
    public static void main(String[] args){
   
   
        System.out.println("Test2.main");
    }
}
public class Student{
   
   

}

如果当前文件中,没有使用其他文件中的类,可以直接运行成功

image.png

如果当前文件中使用类其他文件中的类,那么会出现异常

image.png

ZGC

GC 是java的主要优势之一(另一个是强大的JVM),永远都是java优化的一个核心点.。然而,当GC的STW(stop the world)太长,就会影响应用的响应时间。消除或者减少GC的停顿时长,将会使JAVA对更广泛的引用场景成为一个更具有吸引力的平台。此外,现代系统中可用内存不断增长,用户和程序员希望JVM能够以更高效的方式利用这些内存,并且无需长时间STW。ZGC A Scalable Low-Latency Garbage Collector(Experimental)作为JDK11最瞩目的特征,但是后面带了Experimental,说明是实验版本,也就不建议在生产环境中使用。ZGC是一个并发,基于 region的压缩性垃圾收集器,只有root扫描阶段会STW,因此GC停顿时间不会随着堆的增长和存活对象的增长而变长。

优势:

  • 暂停时间不会超过10ms
  • 既能处理几百兆的小堆,也能处理几个T的大堆(OMG)
  • 和G1相比,应用吞吐能力不会下降超过15%
  • 为未来的GC功能和利用colord指针以及Load Barriers优化奠定基础
  • 初始只支持64位系统

设计目标:

  1. 支持TB级内存容量,暂停时间低(<10ms),对整个程序吞吐量的影响小于15%
  2. 将来还可以扩展实现机制,用以支持很多让人兴奋的功能. 如多层堆或者压缩堆

其他了解

  • unicode10
  • Deprecate The Pack200 Tools and API
  • 新的Epsilon垃圾收集器
  • 完全支持Linux容器,包括Docker
  • 支持G1上的并行完全垃圾收集
  • 最新的HTTPS安全协议TLS 1.3
  • JAVA Flight Recoder
相关文章
|
3月前
|
容器
jdk8新特性-详情查看文档
jdk8新特性-详情查看文档
46 3
|
2月前
|
存储 安全 Java
JDK1.8 新的特性
JDK1.8 新的特性
21 0
|
3月前
|
编解码 安全 Java
jdk8新特性-接口和日期处理
jdk8新特性-接口和日期处理
|
4月前
|
Java API
JDK8到JDK25版本升级的新特性问题之使用Collectors.teeing()来计算一个列表中学生的平均分和总分如何操作
JDK8到JDK25版本升级的新特性问题之使用Collectors.teeing()来计算一个列表中学生的平均分和总分如何操作
|
4月前
|
Java API Apache
JDK8到JDK24版本升级的新特性问题之在Java中,HttpURLConnection有什么局限性,如何解决
JDK8到JDK24版本升级的新特性问题之在Java中,HttpURLConnection有什么局限性,如何解决
|
4月前
|
Oracle Java 关系型数据库
JDK8到JDK29版本升级的新特性问题之未来JDK的升级是否会成为必然趋势,如何理解
JDK8到JDK29版本升级的新特性问题之未来JDK的升级是否会成为必然趋势,如何理解
|
4月前
|
Oracle 安全 Java
JDK8到JDK28版本升级的新特性问题之在Java 15及以后的版本中,密封类和密封接口是怎么工作的
JDK8到JDK28版本升级的新特性问题之在Java 15及以后的版本中,密封类和密封接口是怎么工作的
|
4月前
|
Java API 开发者
JDK8到JDK17版本升级的新特性问题之SpringBoot选择JDK17作为最小支持的Java lts版本意味着什么
JDK8到JDK17版本升级的新特性问题之SpringBoot选择JDK17作为最小支持的Java lts版本意味着什么
134 0
JDK8到JDK17版本升级的新特性问题之SpringBoot选择JDK17作为最小支持的Java lts版本意味着什么
|
3月前
|
Java 编译器 API
JDK8新特性--lambda表达式
JDK8的Lambda表达式是Java语言的一大进步。它为Java程序提供了更多的编程方式,让代码更加简洁,也让函数式编程的概念在Java中得到了体现。Lambda表达式与Java 8的其他新特性,如Stream API、新的日期时间API一起,极大地提高了Java编程的效率和乐趣。随着时间的流逝,Java开发者对这些特性的理解和应用将会越来越深入,进一步推动Java语言和应用程序的发展。
15 0
|
4月前
|
算法 Java iOS开发
JDK8到JDK27版本升级的新特性问题之JDK 17中G1在资源占用方面有何变化
JDK8到JDK27版本升级的新特性问题之JDK 17中G1在资源占用方面有何变化