--- 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中了,所以在挑选第三方库的时候,需要注意第三方库是否有使用这些内容。如果使用了这些被移除的内容,那么就要做一些兼容性处理了。