blog/source/_posts/nf-java11.md
2021-05-21 09:08:17 +08:00

119 lines
5.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: Java 11的新特性
tags:
- JVM
- Java
- Java 11
- 新特性
- 字符串
- 文件操作
- HTTP Client
categories:
- - JVM
- Java
keywords: 'Java,Java 11,LTS,新特性,字符串,文件,操作,HTTP,Client,嵌套'
date: 2021-05-21 08:57:28
---
Java 11是于Java 8之后的第一个LTS长期支持版本虽然距离Java 10的发布只有六个月但是增加的功能却不少。<!-- more -->
本系列的文章有:
- {% post_link nf-java8 %}
- {% post_link nf-java9 %}
- {% post_link nf-java10 %}
- {% post_link nf-java11 %}
- {% post_link nf-java12 %}
- {% post_link nf-java13 %}
- {% post_link nf-java14 %}
- {% post_link nf-java15 %}
- {% post_link nf-java16 %}
## 新字符串操作方法
为了减少第三方库的使用Java 11为字符串操作增加了以下这些新方法。
- `.isBlank()`,判断字符串是否为空白,即其中是否只包含空白字符。
- `.lines()`,返回字符串的行数,行数是由字符串中所包含的换行符和回车符确定的。
- `.strip()`,去除字符串首尾的空白字符。
- `.stripLeading()`、`.stripTrailing()`,分别去除字符串头部和尾部的空白字符。
- `.repeat()`返回重复了指定次数的字符串如果重复次数为0则返回一个空字符串。
在这其中,`.strip()`系列方法的功能与`.trim()`不同,`.strip()`支持空白Unicode字符的清理。
## 新文件操作方法
在`java.nio.file.Files`工具类中加入了直接在文件中读写字符串的静态方法。
- `.readString()`,从指定路径文件中将其内容读取为字符串,或可指定字符串的编码。
- `.writeString()`,向指定路径文件中写入字符串,同样可以指定字符串的编码。
但是这几个直接读写字符串的方法在使用的时候需要注意如果文件体积较大就有可能会出现OOM的情况。
## 新的集合转换方法
在`java.util.Coolection`接口中,新增了一个可以接受`IntFunction<T>`参数的`.toArray()`方法,可以允许将以鞥集合转换为一个有界数组。`IntFunction<T>`的经典代表是数组的构造函数,例如`new String[0]`。
在没有引入这个方法的时候,如果想要把一个集合转换为字符串数组,那么就只能这样书写:`String[] sa = x.toArray(new String[0])`。看起来还需要新创建一个长度为零的字符串数组。所以在引入这个新的`.toArray()`方法以后,这种转换就可以这样来书写了:`String[] sa = x.toArray(String[]::new)`。新版的方法语义感更强,而且节省了一个不必要的创建操作和内存使用。
## 否定谓词方法
`Predicate`接口作为在Java 8中引入的谓词断言接口在Lambda表达式中都非常常用但是在使用过程中我们往往会需要使用否定断言。而在使用否定断言的时候不是需要重新写反向的拍断逻辑就是需要使用`Predicate`接口提供的`.negate()`方法,但是这看起来并不直观,例如`String::isBlank.negate()`。那么在引入否定谓词以后,就可以使用`Predicate.not(String::isBlank)`的形式了,也就变得更加直观了。
## Lambda中的局部变量类型推断
从Java 8引入了Lambda表达式以后Lambda表达式中的局部变量类型一般还是需要显式声明的。Java 11将关键字`var`的使用推广到了Lambda表达式里现在可以使用`var`来让编译器自动推断Lambda表达式的参数类型了。
```java
Stirng joined = stringList.stream()
.map((var x) -> x.toUpperCase())
.collect(Collectors.joining(', '));
```
## HTTP客户端
这个新的HTTP客户端实际上在Java 9里就已经引入了但是当时并不稳定所以被移入了孵化包Incubator里。现在这个功能在Java 11中已经得到了稳定和增强于是就以`java.net.http`包的身份加入了JDK。
新的HTTP客户端支持HTTP/2和WebSocket其主要接口和类有以下四个
- `HttpClient`
- `HttpRequest`
- `HttpResponse<T>`
- `WebSocket`
这四个高级HTTP API可以方便的用来创建HTTP服务和访问。
```java
HttpRequest httpRequest = HttpRequest.newBuilder()
.GET()
.uri(URI.create("http://localhost:" + port))
.build();
HttpResponse httpResponse = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString());
```
## 基于嵌套的访问控制
嵌套类是一个十分常用的结构Java 11在反射里引入了一些新的方法可以用来检查类之间的层级关系。
- `.getNestHost()`,获取嵌套类的宿主类。
- `.getNestMembers()`,获取嵌套类结构中所有的类成员。
- `.isNestmateOf()`,判断指定类是否是当前类的嵌套成员。
## 运行Java源文件
Java是一门编译型语言所以哪怕整个程序只有一个文件也是需要先使用`javac`进行编译以后才能交由`java`运行的。Java 11修改了这个用法现在`java`命令可以直接运行`.java`源文件了。
## 已经移除的API
自从Java 9开始就有一些API被标记为了废弃现在在Java 11版本中已经被彻底移除了。这些被移除的功能主要有以下这些。
- Java API for XML-Based Web Services (java.xml.ws)
- Java Architecture for XML Binding (java.xml.bind)
- JavaBeans Activation Framework (java.activation)
- Common Annotations (java.xml.ws.annotation)
- Common Object Request Broker Architecture (java.corba)
- JavaTransaction API (java.transaction)
- Java Mission Control
- JavaFX
这些已经被移除的API现在都被转移到了第三方管理不再集成在JDK中了所以在挑选第三方库的时候需要注意第三方库是否有使用这些内容。如果使用了这些被移除的内容那么就要做一些兼容性处理了。