Java 11正式发布,这几个逆天新特性教你写出更牛逼的代码

就在前段时间,Oracle 官方宣布 Java 11 (18.9 LTS) 正式发布,可在生产环境中使用! 这无疑对我们来说是一大好的消息。作为一名java开发者来说,虽然又要去学习和了解java11,但内心还是欣慰的。我想至少你和我一样的心情:Java在手,天下我有!

今天我们来看一下Java 11到底是什么、他有什么特别的、到底要不要升级到Java 11。

 

 

Java 11有什么特别的

在Oracle官网中,进入下载页面,第一个可供下载的JDK版本已经提换成了Java SE 11 (LTS),这里的LTS表示Long-Term-Support。

 

 

本次发布的Java 11和2017年9月份发布的Java 9以及 2018年3月份发布的Java 10相比,其最大的区别就是:在长期支持(Long-Term-Support)方面,Oracle表示会对Java 11提供大力支持,这一支持将会持续至2026年9月。这是据 Java 8 以后支持的首个长期版本。

为什么说是长期版本,看下面的官方发布的支持路线图表。

 

 

上图是一张Oracle 公布的对于各个版本的JDK的Support Roadmap。途中列举了Java 6 - Java 12的正式发布时间以及支持计划。

从中可以看出,在Java 11之前,Java 9和Java 10是不提供长期支持的,而上一个提供长期支持的版本是Java 8,其将会支持到2025年3月。

长期支持,表示Oracle会对其做长期的补丁、安全等扩展支持等。

下一个提供长期支持的版本将会是Java 17,其将于2021年发布。

现在大部分都在用 Java 8,Java 9 和 10 目前很少有人在用,至少我没有发现有公司在生产环境应用的,那就是找死。

现在 Java 11 长期支持,也已经包含了 9 和 10 的全部功能,9 和 10 自然就活到头了。。

那么我们来看下 从 Java 9 - 11 都有哪些重要的新特性呢?

新特性

1、本地变量类型推断

什么是局部变量类型推断?

大家看出来了,局部变量类型推断就是左边的类型直接使用 var 定义,而不用写具体的类型,编译器能根据右边的表达式自动推断类型,如上面的 String 。

就等于:

2、字符串加强

Java 11 增加了一系列的字符串处理方法,如以下所示。

" ".isBlank(); // true

// 去除首尾空格

" Javastack ".strip(); // "Javastack"

// 去除尾部空格

" Javastack ".stripTrailing(); // " Javastack"

// 去除首部空格

" Javastack ".stripLeading(); // "Javastack "

// 复制字符串

"Java".repeat(3); // "JavaJavaJava"

// 行数统计

"A\nB\nC".lines().count(); // 3

3、集合加强

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

示例1:

var copy = List.copyOf(list);

System.out.println(list == copy); // true

示例2:

();

var copy = List.copyOf(list);

System.out.println(list == copy); // false

示例1和2代码差不多,为什么一个为true,一个为false?

来看下它们的源码:

List of(E... elements) {
switch (elements.length) { // implicit null check of elements  

    case 0:  

        return ImmutableCollections.emptyList();  

    case 1:  

        return new ImmutableCollections.List12<>(elements[0]);  

    case 2:  

        return new ImmutableCollections.List12<>(elements[0],elements[1]);  

    default:  

        return new ImmutableCollections.ListN<>(elements);  

}  

}

static List copyOf(Collection<? extends E> coll) {

return ImmutableCollections.listCopy(coll);  

}

static List listCopy(Collection<? extends E> coll) {

if (coll instanceof AbstractImmutableList &amp;&amp; coll.getClass() != SubList.class) {  

    return (List<E>)coll;  

} else {  

    return (List<E>)List.of(coll.toArray());  

}  

}

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

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

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

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

4、Stream 加强

Stream 是 Java 8 中的新特性,Java 9 开始对 Stream 增加了以下 4 个新方法。

  1. 增加单个参数构造方法,可为null
    增加 takeWhile 和 dropWhile 方法
.takeWhile(n -> n < 3) .collect(Collectors.toList()); // [1,2] </pre>

从开始计算,当 n < 3 时就截止。

.dropWhile(n -> n < 3) .collect(Collectors.toList()); // [3,1] </pre>

这个和上面的相反,一旦 n < 3 不成立就开始计算。

3)iterate重载

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

如果你对 JDK 8 中的 Stream 还不熟悉,可以看之前分享的这一系列教程。

5、Optional 加强

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

Optional.of("javastack").stream().count(); // 1

Optional.ofNullable(null)

.or(() -> Optional.of("javastack"))  

.get();   // javastack </pre>

6、InputStream 加强

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

var inputStream = classLoader.getResourceAsStream("javastack.txt");

var javastack = File.createTempFile("javastack2","txt");

try (var outputStream = new FileOutputStream(javastack)) {

inputStream.transferTo(outputStream);  

}

7、HTTP Client API

这是 Java 9 开始引入的一个处理 HTTP 请求的的孵化 HTTP Client API,该 API 支持同步和异步,而在 Java 11 中已经为正式可用状态,你可以在 包中找到这个 API。

来看一下 HTTP Client 的用法:

.uri(URI.create("https://javastack.cn")) .GET() .build();

var client = HttpClient.newHttpClient();

// 同步

HttpResponse response = client.send(request,HttpResponse.BodyHandlers.ofString());

System.out.println(response.body());

// 异步

client.sendAsync(request,HttpResponse.BodyHandlers.ofString())

.thenApply(HttpResponse::body)  

.thenAccept(System.out::println); </pre>

上面的 .GET() 可以省略,默认请求方式为 Get!

更多使用示例可以看这个 API,后续有机会再做演示。

现在 Java 自带了这个 HTTP Client API,我们以后还有必要用 Apache 的 HttpClient 工具包吗?

8、化繁为简,一个命令编译运行源代码

看下面的代码。

// 运行
java Javastack

在我们的认知里面,要运行一个 Java 源代码必须先编译,再运行,两步执行动作。而在未来的 Java 11 版本中,通过一个 java 命令就直接搞定了,如以下所示。

更多新特性

新发布的Java 11在新特性方面,提供了17个JEP(JDK Enhancement Proposal 特性增强提议)

 

上图是Oracle公布的Java 11包含的所有新特性,其中几个重点的新特性为:

ZGC:可扩展的低延迟垃圾收集器

ZGC是一款号称可以保证每次GC的停顿时间不超过10MS的垃圾回收器,并且和当前的默认垃圾回收起G1相比,吞吐量下降不超过15%。

Epsilon:什么事也不做的垃圾回收器

Java 11还加入了一个比较特殊的垃圾回收器——Epsilon,该垃圾收集器被称为“no-op”收集器,将处理内存分配而不实施任何实际的内存回收机制。 也就是说,这是一款不做垃圾回收的垃圾回收器。这个垃圾回收器看起来并没什么用,主要可以用来进行性能测试、内存压力测试等,Epsilon GC可以作为度量其他垃圾回收器性能的对照组。大神Martijn说,Epsilon GC至少能够帮助理解GC的接口,有助于成就一个更加模块化的JVM。

增强var用法

Java 10中增加了本地变量类型推断的特性,可以使用var来定义局部变量。尽管这一特性被很多人诟病,但是并不影响Java继续增强他的用法,在Java 11中,var可以用来作为Lambda表达式的局部变量声明。

移除Java EE和CORBA模块

早在发布Java SE 9的时候,Java就表示过,会在未来版本中将Java EE和CORBA模块移除,而这样举动终于在Java 11中实施。终于去除了Java EE和CORBA模块。

HTTP客户端进一步升级

JDK 9 中就已对 HTTP Client API 进行标准化,然后通过JEP 110,在 JDK 10 中进行了更新。在本次的Java 11的更新列表中,由以JEP 321进行进一步升级。该API通过CompleteableFutures提供非阻塞请求和响应语义,可以联合使用以触发相应的动作。 JDK 11完全重写了该功能。现在,在用户层请求发布者和响应发布者与底层套接字之间追踪数据流更容易了,这降低了复杂性,并最大程度上提高了HTTP / 1和HTTP / 2之间的重用的可能性。

到底要不要升级

2017年8月,JCP执行委员会提出将Java的发布频率改为每六个月一次。

  • 2017年9月,Java 9发布。
  • 2018年3月,Java 10发布。
  • 2018年9月,Java 11发布。

大部分人使用的JDK版本还是Java 8及以下版本,甚至某些公司的生产环境使用的还是JDK 1.6。

那么,对于公司和开发者来说,到底要不要在生产及开发环境中升级和学习Java 11呢?

对于企业来说

对于企业来说,生产环境中的JDK版本升级到Java 11还是有必要的。主要有两个原因:

1、Oracle会对Java 11提供长期支持,企业可以放心使用这一版本。并且下一个长期支持的版本会在三年后发布,时间比较久远。

2、Java 11确实提供了一些比较不错的特性,尤其重要的是提供了ZGC,这是一款具有划时代意义的垃圾回收器。优点不再赘述。有了ZGC,JVM的性能瓶颈可以被突破。

对于开发者来说

在编码方面,Java 11并没有像Java 8那样变化巨大,毕竟Java 8提供了函数式编程的能力,这也是很多开发者学习Java 8的一个重要原因。

但是,Java 11也并不是完全没有提升,至少在新版本中,Java开发者终于可以摆脱老旧的HttpURLConnection了。新的HTTP API提供了对HTTOP/2等业界前沿标准的支持,提供了精简而又友好的API接口。

所以,综上所述,无论是对于企业还是开发者来说,升级Java 11都是有必要的,至少比Java 9和Java 10的必要性要大很多。至于这个必要性到底有多大呢,作者给一个简单的说明:

  • 如果你现在时候用的JDK/Java版本低于Java 8,先升级到Java 8。
  • 如果你现在时候用的JDK/Java版本高于Java 7,那么可以考虑升级到Java 11了。 当然,你可以直接从Java 6跳跃到Java 11。

现在许多人还在使用 Java 8 或者 7,不过 8 在 2019 年初就会结束免费更新。现在 11 是长期支持版本,正是学习和上手 11 的好时机,写这篇文章希望能对你有所启发。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


本文从从Bitcask存储模型讲起,谈轻量级KV系统设计与实现。从来没有最好的K-V系统,只有最适合应用业务实际场景的系统,做任何的方案选择,要结合业务当前的实际情况综合权衡,有所取有所舍。
内部的放到gitlab pages的博客,需要统计PV,不蒜子不能准确统计,原因在于gitlab的host设置了strict-origin-when-cross-origin, 导致不蒜子不能正确获取referer,从而PV只能统计到网站的PV。 为了方便统计页面的PV,这里简单的写了一个java程
PCM 自然界中的声音非常复杂,波形极其复杂,通常我们采用的是脉冲代码调制编码,即PCM编码。PCM通过抽样、量化、编码三个步骤将连续变化的模拟信号转换为数字编码。 采样率 采样频率,也称为采样速度或者采样率,定义了每秒从连续信号中提取并组成离散信号的采样个数,它用赫兹(Hz)来表示。采样频率的倒数
本文介绍如何离线生成sst并在线加载,提供一种用rocksdb建立分布式kv系统替换mongodb的思路
验证用户输入是否正确是我们应用程序中的常见功能。Spring提供了`@Valid`和@`Validated`两个注解来实现验证功能,本文详细介绍 [@Valid]和[@Validated]注解的区别 。
引入pdf2dom &lt;dependency&gt; &lt;groupId&gt;net.sf.cssbox&lt;/groupId&gt; &lt;artifactId&gt;pdf2dom&lt;/artifactId&gt; &lt;version&gt;1.8&lt;/version&
grafana 是一款非常优秀的可视化报表工具,有设计精良的可视化工具,今天来聊一聊如何将grafana集成到自己的应用中。 原理是: grafana允许iframe访问,开启auth.proxy, java 后端鉴权后代理grafana 前端通过iframe访问后端代理过的grafana graf
介绍 Call Graph是一款IDEA插件,用于可视化基于IntelliJ平台的IDE的函数调用图。 这个插件的目标是让代码更容易理解,有助于读懂和调试代码。当前只支持Java。针对Typescript、Javascript或Python工具,可以使用作者的另外一款工具Codemap(https:
原理 通过线程安全findAndModify 实现锁 实现 定义锁存储对象: /** * mongodb 分布式锁 */ @Data @NoArgsConstructor @AllArgsConstructor @Document(collection = &quot;distributed-loc
Singleton 单例模式 单例模式是确保每个应用程序只存在一个实例的机制。默认情况下,Spring将所有bean创建为单例。 你用@Autowired获取的bean,全局唯一。 @RestController public class LibraryController { @Autowired
pipeline 分布式任务调度器 目标: 基于docker的布式任务调度器, 比quartzs,xxl-job 更强大的分布式任务调度器。 可以将要执行的任务打包为docker镜像,或者选择已有镜像,自定义脚本程序,通过pipeline框架来实现调度。 开源地址: https://github.c
python训练的模型,转换为onnx模型后,用python代码可以方便进行推理,但是java代码如何实现呢? 首先ONNX 推理,可以使用`onnxruntime` ```xml com.microsoft.onnxruntime onnxruntime 1.15.1 ``` 另外,训练的模型需要
要获取内网地址,可以尝试连接到10.255.255.255:1。如果连接成功,获取本地套接字的地址信息就是当前的内网IP。 python实现: ```python import socket def extract_ip(): st = socket.socket(socket.AF_INET, s
为什么要有索引 gremlin 其实是一个逐级过滤的运行机制,比如下面的一个简单的gremlin查询语句: g.V().hasLabel(&quot;label&quot;).has(&quot;prop&quot;,&quot;value&quot;) 运行原理就是: 找出所有的顶点V 然后过滤出
最近在分析一个应用中的某个接口的耗时情况时,发现一个看起来极其普通的对象创建操作,竟然每次需要消耗 8ms 左右时间,分析后发现这个对象可以通过对象池模式进行优化,优化后此步耗时仅有 0.01ms。
点赞再看,动力无限。Hello world : ) 微信搜「 程序猿阿朗 」。 本文 Github.com/niumoo/JavaNotes 和 未读代码网站 已经收录,有很多知识点和系列文章。 此篇文章介绍 Java JMX 技术的相关概念和具体的使用方式。 当前文章属于Java 性能分析优化系列
如何将Java JAR 转化为 win/mac/linux 独立可执行程序?不需要预装 JRE 运行?
点赞再看,动力无限。 微信搜「 程序猿阿朗 」。 本文 Github.com/niumoo/JavaNotes 和 未读代码博客 已经收录,有很多知识点和系列文章。 Java 19 在2022 年 9 月 20 日正式发布,Java 19 不是一个长期支持版本,直到 2023 年 3 月它将被 JD
点赞再看,动力无限。Hello world : ) 微信搜「 程序猿阿朗 」。 本文 Github.com/niumoo/JavaNotes 和 未读代码博客 已经收录,有很多知识点和系列文章。 前言 Java 反编译,一听可能觉得高深莫测,其实反编译并不是什么特别高级的操作,Java 对于 Cla
JSON 对于开发者并不陌生,如今的 WEB 服务、移动应用、甚至物联网大多都是以 **JSON** 作为数据交换的格式。学习 JSON 格式的操作工具对开发者来说是必不可少的。这篇文章将介绍如何使用 **Jackson** 开源工具库对 JSON 进行常见操作。