Java 11簡介
區域性變數型別推斷
Java 10引入了一個新的語言關鍵字var,它可以在宣告區域性變數時替換型別資訊(本地意味著方法體內的變數宣告)。
在Java 10之前,你將如下宣告變數:
String text = "Hello Java 9";
現在,你可以替換String使用var。編譯器從變數的賦值中推斷出正確的型別。在這種情況下text是型別String:
var text = "Hello Java 10";
宣告的變數var仍然是靜態型別。你無法將不相容的型別重新分配給此類變數。下面程式碼段無法編譯:
var text = "Hello Java 11";
text = 23; // Incompatible types
你還可以結合final禁止將var變數重新分配給另一個值:
final var text = "Banana";
text = "Joe"; // Cannot assign a value to final variable 'text'
如果編譯器無法推斷出var正確的變數型別時,這是無法透過編譯的。以下所有程式碼示例都會導致編譯器錯誤:
// Cannot infer type:
var a;
var nothing = null;
var lambda = () -> System.out.println("Pity!");
var method = this::someMethod;
區域性變數型別推斷確實涉及泛型。在下一個示例中,current有一個相當冗長的型別Map<String, List<Integer>>,可以簡化為單個var關鍵字,從而節省你輸入大量模板程式碼:
var myList = new ArrayList<Map<String, List<Integer>>>(); for (var current : myList) { // current is infered to type: Map<String, List<Integer>> System.out.println(current); } <p class="indent"> |
從Java 11開始var也可以用作lambda引數,從而能為這些引數新增註釋:
Predicate<String> predicate = (@Nullable var a) -> true; <p class="indent"> |
提示:在Intellij IDEA中,你可以將滑鼠懸停在變數上,同時按CMD/CTRL顯示變數的感應型別(按鍵盤愛好者按下CTRL + J)。
HTTP客戶端
Java 9引入了一個HttpClient用於處理HTTP請求的新的API。從Java 11開始,這個API現在是最終完成,可以在標準庫包java.net中找到。讓我們來探索一下我們可以用這個API做些什麼。
新的HttpClient可以同步或非同步使用。同步請求會阻止當前執行緒,直到響應可用。BodyHandlers定義響應體的預期型別(例如,字串,位元組陣列或檔案):
var request = HttpRequest.newBuilder() .uri(URI.create("https://winterbe.com")) .GET() .build(); var client = HttpClient.newHttpClient(); HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); System.out.println(response.body()); <p class="indent"> |
可以非同步執行相同的請求。呼叫sendAsync不會阻塞當前執行緒,而是返回一個CompletableFuture構造非同步操作管道。
var request = HttpRequest.newBuilder() .uri(URI.create("https://winterbe.com")) .build(); var client = HttpClient.newHttpClient(); client.sendAsync(request, HttpResponse.BodyHandlers.ofString()) .thenApply(HttpResponse::body) .thenAccept(System.out::println); <p class="indent"> |
我們可以省略.GET()呼叫,因為它是預設的請求方法。
下一個示例透過傳送資料到指定的URL進行POST。類似BodyHandlers你可以用BodyPublishers來定義要作為請求主體傳送的資料型別,如字串,位元組陣列,檔案或輸入流:
var request = HttpRequest.newBuilder() .uri(URI.create("https://postman-echo.com/post")) .header("Content-Type", "text/plain") .POST(HttpRequest.BodyPublishers.ofString("Hi there!")) .build(); var client = HttpClient.newHttpClient(); var response = client.send(request, HttpResponse.BodyHandlers.ofString()); System.out.println(response.statusCode()); // 200 <p class="indent"> |
最後一個示例演示如何透過BASIC-AUTH以下方式執行授權
var request = HttpRequest.newBuilder() .uri(URI.create("https://postman-echo.com/basic-auth")) .build(); var client = HttpClient.newBuilder() .authenticator(new Authenticator() { @Override protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication("postman", "password".toCharArray()); } }) .build(); var response = client.send(request, HttpResponse.BodyHandlers.ofString()); System.out.println(response.statusCode()); // 200 <p class="indent"> |
集合
諸如集合List,Set並且Map已經用新方法擴充套件。List.of從指定的引數建立了一個新的不可變列表。List.copyOf建立列表的不可變副本。
var list = List.of("A", "B", "C"); var copy = List.copyOf(list); System.out.println(list == copy); // true <p class="indent"> |
因為list已經是不可改變的,就沒有實際需要建立這種列表例項的一個副本,因此list和copy是相同的例項。但是,如果你複製一個可變列表,copy確實是一個新例項,所以它保證在改變原始列表時沒有副作用:
var list = new ArrayList<String>(); var copy = List.copyOf(list); System.out.println(list == copy); // false <p class="indent"> |
建立不可變map時,你不必自己建立map條目,而是將鍵和值作為引數傳遞:
var map = Map.of("A", 1, "B", 2); System.out.println(map); // {B=2, A=1} <p class="indent"> |
Java 11中的不可變集合仍然使用舊Collection API中的相同介面。但是,如果嘗試透過新增或刪除元素來修改不可變集合,則丟擲java.lang.UnsupportedOperationException。
幸運的是,如果你嘗試改變不可變集合,Intellij IDEA會透過檢查發出警告。
流
Streams是在Java 8中引入的,現在有三種新方法。Stream.ofNullable是從單個元素構造流:
Stream.ofNullable(null) .count() // 0 <p class="indent"> |
方法dropWhile和takeWhile都接受謂詞來確定從流中放棄哪些元素:
Stream.of(1, 2, 3, 2, 1) .dropWhile(n -> n < 3) .collect(Collectors.toList()); // [3, 2, 1] Stream.of(1, 2, 3, 2, 1) .takeWhile(n -> n < 3) .collect(Collectors.toList()); // [1, 2] <p class="indent"> |
Optionals
Optionals還會有一些非常方便的新方法,例如,你現在可以簡單地將Optionals轉換為流,或者為空Optionals提供另一個可選的後備:
Optional.of("foo").orElseThrow(); // foo Optional.of("foo").stream().count(); // 1 Optional.ofNullable(null) .or(() -> Optional.of("fallback")) .get(); // fallback <p class="indent"> |
String字串
最基本的類之一String新增一些輔助方法來修剪或檢查空格以及流式傳輸字串的行:
" ".isBlank(); // true " Foo Bar ".strip(); // "Foo Bar" " Foo Bar ".stripTrailing(); // " Foo Bar" " Foo Bar ".stripLeading(); // "Foo Bar " "Java".repeat(3); // "JavaJavaJava" "A\nB\nC".lines().count(); // 3 <p class="indent"> |
InputStreams
最後但並非最不重要的是,InputStream最終獲得了一種非常有用的方法來將資料傳輸到一個OutputStream,這是在處理原始資料流時非常常見的用例。
var classLoader = ClassLoader.getSystemClassLoader(); var inputStream = classLoader.getResourceAsStream("myFile.txt"); var tempFile = File.createTempFile("myFileCopy", "txt"); try (var outputStream = new FileOutputStream(tempFile)) { inputStream.transferTo(outputStream); } <p class="indent"> |
相關文章
- JAVA簡介Java
- java JNI簡介Java
- Java 反射簡介Java反射
- Java scirpt簡介Java
- java agent簡介Java
- Java Class物件簡介Java物件
- MySQL原理簡介—11.最佳化案例介紹MySql
- Java中Stalactite ORM簡介JavaORM
- JAVA阻塞IO(BIO)簡介Java
- Java學習:JDBC簡介JavaJDBC
- Java集合四:Map簡介;Java
- ECMAScript 2020(ES11)新特性簡介
- 【Java初探01】——Java簡介及相關Java
- JAVA輕量級鎖簡介Java
- Java記憶體模型簡介Java記憶體模型
- Java記憶體模型 - 簡介Java記憶體模型
- java簡介--環境安裝Java
- java中的編碼簡介Java
- 【譯】Java NIO 簡明教程系列之 NIO 簡介Java
- java註解的簡單介紹Java
- Java程式語言特點簡介Java
- Java中使用JMX除錯簡介Java除錯
- Java設計模式簡介(總結)Java設計模式
- 簡單介紹Java String Methods(上)Java
- 簡單介紹Java String Methods(下)Java
- Java高併發之CyclicBarrier簡介Java
- Java入門到實踐系列(1)——Java簡介Java
- 什麼是JPA?Java Persistence API簡介JavaAPI
- Java正規表示式簡單介紹Java
- Java之HashMap集合簡介及遍歷JavaHashMap
- JSON簡介(java中的json庫使用)JSONJava
- JAVA基礎之六-Stream(流)簡介Java
- Java常量池解析與字串intern簡介Java字串
- 實用函式式 Java (PFJ)簡介函式Java
- Java併發:ThreadLocal的簡單介紹Javathread
- 簡單介紹java中的equals()方法Java
- java設計模式一一設計模式的簡介和介紹Java設計模式
- 助力Java系統元件化:Navi框架簡介Java元件化框架