JDK8 - 轉- JDK11 -轉- JDK17
JShell(JDK9開始支持)
G:\dowload\JDK\JDK11\jdk-11.0.2\bin ===> C:\Windows\System32\cmd.exe
var 局部變量的類型推導
var 不可以作用修飾成員變量。注意var不是關鍵字,僅僅是語法的改進。
int var = 100;//是有效的
var不是關鍵字,注意var推斷的是接收變量的類型,如果接收變量未定義,那么無效且編譯不通過!
var a;//不成立,編譯不通過,因為無法推斷!
JDK1.7開始的:
List
list = new ArrayList<>();//左邊的泛型依賴右邊的泛型
JDK9開始:
var temp = "Hello World" ;
等價於
String temp = "Hello World" ;
var的最主要的用途一般是用於lambda表達式中!
(@NotNull var t,@NotNull var y)->t.eques(y);
JDK11新添加API
集合API增強
創建固定長度的集合
@Test
public void testList() {
String[] tempNumber = {"abc", "def", "ghi", "jkl", "mno", "pqr"};
//以前創建集合
List<String> stringByList01 = new ArrayList<>();
for (int i = 0; i < tempNumber.length; i++) {
stringByList01.add(tempNumber[i]);
}
System.out.println(stringByList01);
//第一次進階
stringByList01 = new ArrayList<>(Arrays.asList(tempNumber));
//注意Arrays.asList返回的也不是util包下的ArrayList,是Arrays內部類名稱也為ArrayList,兩個不等同,所以不能添加新元素,異常:不支持操作異常
System.out.println(stringByList01);
//JDK11 List.of(...)
List<String> stringByList = List.of(tempNumber);
System.out.println(stringByList);
//stringByList.getClass() = > ImmutableCollections$ListN(不可改變的集合),返回的也不是util包下的ArrayList,也是不能添加新元素
}
同理set創建固定集合
@Test
public void tetSet(){
Set<Integer> integers = Set.of(123, 23, 43, 53, 65, 76, 73, 34, 54);
System.out.println(integers);
//注意,如果set的of方法里面有重復元素,直接拋異常
//IllegalArgumentException
integers = Set.of(123, 23, 43, 53, 65, 123, 23, 43, 53);
System.out.println(integers);
}
JDK11對於流的改進
@Test
public void streamTest() {
//Stream 流處理創建也是可以使用of方法
Stream<String> stream = Stream.of("5", "2", "1", "4");
//排序和打印
stream.sorted(String::compareTo).forEach(System.out::println);
//可以Stream.of(),但是不可以Stream.of(null);是空指針異常
//JDK11的有傳入null的流的創建
Stream<Object> objectStream = Stream.ofNullable(null);
System.out.println(objectStream);
//JDK11的新方法takeWhile
Stream<Integer> integerStream = Stream.of(2, 4, 6, 7, 8);
//就是遍歷判定是否滿足條件,滿足的放入新的流中,一旦遇到不滿足的就即刻終止遍歷
Stream<Integer> takeWhile = integerStream.takeWhile(t -> t % 2 == 0);
takeWhile.forEach(x -> System.out.print(x + ","));
System.out.println();
//JDK11的新方法dropWhile
Stream<Integer> dropWhileStream = Stream.of(2, 4, 6, 7, 8);
//就是遍歷判定是否滿足條件,不滿足的丟棄,一旦遇到滿足的就將它和他后面的元素丟入新的流中
Stream<Integer> dropWhile = dropWhileStream.dropWhile(t -> t % 2 == 0);
dropWhile.forEach(x -> System.out.print(x + ","));
//JDK8 流的無限流,迭代
Stream<Integer> iterate = Stream.iterate(1, t -> 2 * t + 1);
iterate.limit(10).forEach(x -> System.out.print(x + ","));
//JDK11 解決無限流,迭代:中間有一個條件終止無限流,轉化為有限流
Stream<Integer> youxianliu = Stream.iterate(1, t -> t < 1000, t -> 2 * t + 1);
youxianliu.limit(10).forEach(x -> System.out.print(x + ","));
}
String增強API
@Test
public void stringTest() {
//JDK11字符串新增方法
String str = " \t \n";
//判斷字符串是否為空白:
boolean blank = str.isBlank();
System.out.println(blank);
//JDK11.去除字符串首尾的空白:處理各種語言的空白字符
String strip = str.strip();// 原來的首尾ASCII碼小於32的空格去除:str.trim(),
System.out.println(strip);
//去除尾部或者首部的空白
String index = str.stripLeading();
String last = str.stripTrailing();
// 判斷字符串是否為空白
" ".isBlank(); // true
// 去除首尾空格
" Javastack ".strip(); // "Javastack"
// 去除尾部空格
" Javastack ".stripTrailing(); // " Javastack"
// 去除首部空格
" Javastack ".stripLeading(); // "Javastack "
// 復制字符串
"Java".repeat(3);// "JavaJavaJava"
// 行數統計
"A\nB\nC".lines().count(); // 3
}
Optional增強:Opthonal 也增加了幾個非常酷的方法,現在可以很方便的將一個 Optional 轉換成一個 Stream, 或者當一個空 Optional 時給它一個替代的。
//java ~
String res1 = Optional.of( "java ~" ).orElseThrow();
System.out.println(res1);
//1
long res2 = Optional.of( "java ~" ).stream().count();
System.out.println(res2);
//java ~
Object res3 = Optional.ofNullable( null )
.or( () -> Optional.of( "java ~" ) )
.get();
System.out.println(res3);
輸入流增強api:
transferTo,可以用來將數據直接傳輸到OutputStream,這是在處理原始數據流時非常常見的一種用法。
try {
InputStream inputStream = TestInputStream.class.getClassLoader().getResourceAsStream("test.txt");
var file = new File("/Users/xxx/test2.txt");
try (var outputStream = new FileOutputStream(file)) {
inputStream.transferTo(outputStream);
}
} catch (IOException e) {
e.printStackTrace();
}
HTTP客戶端增強api
這是 Java 9 開始引入的一個處理 HTTP 請求的的孵化 HTTP Client API,該 API 支持同步和異步,而在 Java 11 中已經為正式可用狀態,你可以在 java.net 包中找到這個 API。
try {
var request = HttpRequest.newBuilder()
.uri( URI.create("http://t.weather.sojson.com/api/weather/city/101020100"))
.GET()
.build();
var client = HttpClient.newHttpClient();
// 同步
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
//異步
client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
.thenApply(HttpResponse::body)
.thenAccept(System.out::println)
.join();
} catch (Exception e) {
e.printStackTrace();
}
工作中異常:IOException, InterruptedException, ExecutionException
讀寫文件
對Files類增加了writeString和readString兩個靜態方法,可以直接把String寫入文件,或者把整個文件讀出為一個String:
Files.writeString(
Path.of("./", "tmp.txt"), // 路徑
"hello, jdk11 files api", // 內容
StandardCharsets.UTF_8); // 編碼
String s = Files.readString(
Paths.get("./tmp.txt"), // 路徑
StandardCharsets.UTF_8); // 編碼
JDK11還帶來了EpsilonGC,就是什么也不做的GC,以及ZGC,一個幾乎可以做到毫秒級暫停的GC。ZGC還處於實驗階段,所以啟動它需要命令行參數
-XX:+UnlockExperimentalVMOptions -XX:+UseZGC
。
ZGC
ZGC, 這應該是JDK11最為矚目的特性, 沒有之一. 但是后面帶了Experimental, 說明這還不建議用到生產環境。 GC暫停時間不會超過10ms,既能處理幾百兆的小堆, 也能處理幾個T的大堆(OMG),和G1相比, 應用吞吐能力不會下降超過15%,為未來的GC功能和利用colord指針以及Load barriers優化奠定基礎,初始只支持64位系統 ZGC的設計目標是:支持TB級內存容量,暫停時間低(<10ms),對整個程序吞吐量的影響小於15%。 將來還可以擴展實現機制,以支持不少令人興奮的功能,例如多層堆(即熱對象置於DRAM和冷對象置於NVMe閃存),或壓縮堆。 GC是java主要優勢之一,當GC停頓太長, 就會開始影響應用的響應時間.消除或者減少GC停頓時長, java將對更廣泛的應用場景是一個更有吸引力的平台. 此外, 現代系統中可用內存不斷增長,用戶和程序員希望JVM能夠以高效的方式充分利用這些內存, 並且無需長時間的GC暫停時間
用法 : -XX:+UnlockExperimentalVMOptions –XX:+UseZGC, 因為ZGC還處於實驗階段, 所以需要通過JVM參數來解鎖這個特性
完全支持Linux容器(包括Docker)
許多運行在Java虛擬機中的應用程序(包括Apache Spark和Kafka等數據服務以及傳統的企業應用程序)都可以在Docker容器中運行。但是在Docker容器中運行Java應用程序一直存在一個問題,那就是在容器中運行JVM程序在設置內存大小和CPU使用率后,會導致應用程序的性能下降。這是因為Java應用程序沒有意識到它正在容器中運行。隨着Java 10的發布,這個問題總算得以解決,JVM現在可以識別由容器控制組(cgroups)設置的約束。可以在容器中使用內存和CPU約束來直接管理Java應用程序,其中包括:
遵守容器中設置的內存限制
在容器中設置可用的CPU
在容器中設置CPU約束
Java 10的這個改進在Docker for Mac、Docker for Windows以及Docker Enterprise Edition等環境均有效。
容器的內存限制
在Java 9之前,JVM無法識別容器使用標志設置的內存限制和CPU限制。而在Java 10中,內存限制會自動被識別並強制執行。Java將服務器類機定義為具有2個CPU和2GB內存,以及默認堆大小為物理內存的1/4。
支持G1上的並行完全垃圾收集對於 G1 GC,相比於JDK 8,升級到JDK 11即可免費享受到:並行的Full GC,快速的CardTable掃描,自適應的堆占用比例調整(IHOP),在並發標記階段的類型卸載等等。這些都是針對G1的不斷增強,其中串行Full GC等甚至是曾經被廣泛詬病的短板,你會發現GC配置和調優在JDK11中越來越方便。