diff --git a/source/_posts/nf-java11.md b/source/_posts/nf-java11.md new file mode 100644 index 0000000..8227e74 --- /dev/null +++ b/source/_posts/nf-java11.md @@ -0,0 +1,119 @@ +--- +title: Java 11的新特性 +tags: + - JVM + - Java + - Java 11 + - 新特性 + - 字符串 + - 文件操作 + - HTTP Client +categories: + - - JVM + - Java +keywords: '' +date: 2021-05-21 08:57:28 +--- + +Java 11是于Java 8之后的第一个LTS(长期支持)版本,虽然距离Java 10的发布只有六个月,但是增加的功能却不少。 + +本系列的文章有: + +- {% 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`参数的`.toArray()`方法,可以允许将以鞥集合转换为一个有界数组。`IntFunction`的经典代表是数组的构造函数,例如`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` +- `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中了,所以在挑选第三方库的时候,需要注意第三方库是否有使用这些内容。如果使用了这些被移除的内容,那么就要做一些兼容性处理了。 \ No newline at end of file