Java SE 11 新增特性
Java SE 11 新增特性
作者:Grey
原文地址:Java SE 11 新增特性
源碼
鏡像倉庫: GitCode:java_new_features
Lambda 類型推斷
JDK 10引入了局部變數類型推理(JEP 286)。這簡化了程式碼,因為你不再需要明確說明局部變數的類型,而是可以使用var
。JEP 323將這種語法的使用擴展到Lambda表達式的參數。這裡有一個簡單的例子。
package git.snippets.jdk11;
import java.util.HashMap;
import java.util.Map;
/**
* lambda類型推斷
*
* @author <a href="mailto:[email protected]">Grey</a>
* @date 2021/11/29
* @since 11
*/
public class LambdaInfer {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<>(2);
map.put("hello", 1);
map.put("world", 2);
map.forEach((var s, var i) -> System.out.println(s + " " + i));
}
}
單命令行運行Java
原先需要javac
,然後java
javac Hello.java && java Hello
現在合成一個java
命令搞定
java Hello.java
同樣的
java -classpath /home/foo/java Hello.java Bonjour
等同於如下兩條
javac -classpath /home/foo/java Hello.java
java -classpath /home/foo/java Hello Bonjour
該JEP還提供「shebang」支援。為了減少在命令行上提及Java
啟動器的需要,包含在源文件的第一行。例如:
# !/usr/bin/java --source 11
public class HelloWorld {
...
}
註:--source 11
是必要的,指定了JDK
的版本。
HTTP 客戶端
JDK 9 引入了一個新的 API 來提供支援 HTTP 客戶端協議,該API被作為孵化器模組包含在內。孵化器模組旨在提供新的 API,而不會使它們成為Java SE標準的一部分。開發人員可以試用 API 並提供回饋。
HTTP Client API 現在是Java SE 11標準的一部分。JDK 引入了一個新的模組和包:java.net.http
。該 API 可以同步或非同步使用。
示例程式碼如下
package git.snippets.jdk11;
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
/**
* jdk9 中httpclient還在jdk.incubator.httpclient模組中
*
* @author <a href="mailto:[email protected]">Grey</a>
* @date 2021/11/29
* @since 11
*/
public class HttpClientTest {
public static void main(String[] args) throws IOException, InterruptedException {
HttpClient client = HttpClient.newHttpClient();
URI uri = URI.create("//httpbin.org/get");
HttpRequest req = HttpRequest.newBuilder(uri).header("accept", "application/json").GET().build();
HttpResponse<String> resp = client.send(req, HttpResponse.BodyHandlers.ofString());
String body = resp.body();
System.out.println(body);
}
}
執行後控制台輸出
{
"args": {},
"headers": {
"Accept": "application/json",
"Content-Length": "0",
"Host": "httpbin.org",
"Http2-Settings": "AAEAAEAAAAIAAAABAAMAAABkAAQBAAAAAAUAAEAA",
"Upgrade": "h2c",
"User-Agent": "Java-http-client/18.0.1",
"X-Amzn-Trace-Id": "Root=1-62fddb2a-7813af3246da12d203c31825"
},
"origin": "211.136.194.3",
"url": "//httpbin.org/get"
}
移除 Java EE 和 CORBA 模組
隨著 JDK 9 中 JPMS 的引入,可以將整體式 rt.jar 文件劃分為多個模組。JPMS 的另一個優點是,現在可以創建一個僅包含應用程式所需模組的 Java 運行時,從而大大減小了依賴包的大小。通過明確定義的模組邊界,現在可以更輕鬆地刪除 Java API 中過時的部分。
java.se.ee
元模組包括六個模組,這些模組將不再是 Java SE 11 標準的一部分,也不再包含在 JDK 中。受影響的模組包括:
-
corba
-
transaction
-
activation
-
xml.bind
-
xml.ws
-
xml.ws.annotation
自 JDK 9 以來,這些模組已被棄用,並且默認情況下未包含在編譯或運行時中。如果您嘗試編譯或運行一個應用程式,該應用程式在 JDK 9 或 JDK 10 上使用這些模組中的 API 的時候會報錯。如果在程式碼中使用這些模組中的 API,則需要將它們作為單獨的模組或庫提供。
jdeprscan
JDK提供了jdeprscan 來檢查你的程式碼是否使用了deprecated的方法.
JDK 10 到 JDK 11 所有涉及調整的API清單
舉幾個例子,String
類中增加了很多有用的 API。
package git.snippets.jdk11;
/**
* String 新增API
*
* @author <a href="mailto:[email protected]">Grey</a>
* @date 2021/11/29
* @see String
* @since 11
*/
public class StringNewAPI {
public static void main(String[] args) {
isBlankTest();
linesTest();
repeatTest();
stripTest();
}
// 按行列印
private static void linesTest() {
String abcd = "\na\nb\tc\td";
abcd.lines().forEach(System.out::println);
}
// String.isBlank()
private static void isBlankTest() {
String blank = " ";
System.out.println(blank.isBlank());
}
static void repeatTest() {
String repeat = "abcd";
// repeat(n) 表示複製幾次
String repeat3 = repeat.repeat(3);
System.out.println(repeat3);
}
//trim 只能去除半形空格,而 strip 是去除各種空白符。
static void stripTest() {
String a = " bbbd a ";
String b = a.strip();
System.out.println(b);
System.out.println(a);
String strip = " 我是 ";
// 去前面空白字元,如全形空格,TAB
System.out.println("==" + strip.stripLeading() + "==");
// 去後面空白字元,如全形空格,TAB
System.out.println("==" + strip.stripTrailing() + "==");
}
}
File
中增加了一些 API,比如Files.writeString
和 Files.readString
package git.snippets.jdk11;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
/**
* File增強API
*
* @author <a href="mailto:[email protected]">Grey</a>
* @date 2021/11/29
* @since
*/
public class FileNewAPI {
public static void main(String[] args) throws IOException {
testFile();
}
static void testFile() throws IOException {
// 創建臨時文件
Path path = Files.writeString(Files.createTempFile("test", ".txt"), "hello world,你好,世界");
System.out.println(path);
// 讀取文件
// String ss = Files.readString(Path.of("file.json"));
String s = Files.readString(path);
System.out.println(s);
}
}
Optional
和Predicate
相關 API 增強
package git.snippets.jdk11;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Predicate;
import java.util.stream.Collectors;
/**
* Optional用法
*
* @author <a href="mailto:[email protected]">Grey</a>
* @date 2021/11/19
* @since 11
*/
public class OptionalAndPredicateTest {
public static void main(String[] args) {
Optional<String> helloOptional = Optional.of("Hello");
Optional<String> emptyOptional = Optional.empty();
helloOptional.ifPresent(s -> System.out.println(s.length()));
emptyOptional.ifPresent(s -> System.out.println(s.length()));
List<String> lines = Arrays.asList("a", " ", "", null, "b");
List<String> ans = lines.stream().filter(Objects::nonNull).filter(Predicate.not(String::isBlank)).collect(Collectors.toList());
System.out.println(ans);
}
}
JDK 10 到 JDK 11 所有涉及調整的API清單見:JDK 10.0.2 to 11+28 API Change Report
更多
參考資料
90 New Features and APIs in JDK 11 (Part 1)
90 New Features and APIs in JDK 11 (Part 2)
JDK 10.0.2 to 11+28 API Change Report