不少初學Java的小夥伴常常諮詢:java
是這樣,官網如今其實都已經出到Java 13版本了,而且提供下載使用。python
但目前市場上主流的穩定版固然還得屬Java 8和Java 11,而目前大部分公司的生產環境仍是Java 8
居多。因此若是從自學角度出發,我以爲這兩個版本都OK,其餘中間的一些好比Java 9
、Java 10
這些非穩定版就不用考慮了。編程
Java 11相對於Java 8確實有一部分進化,除了有不少內部的升級(好比開銷和時延更低的GC、TLS1.3加持等等)以外,對於初學使用者來講也有一些語言使用層面的進化。oracle
正好最近我在本身的我的小項目上嘗試升級使用了一下Java 11
(公司項目咱也不敢動、也不敢問,只好動本身的我的項目),所以本文從實際代碼編寫角度來大體體驗一下我我的使用Java 11
以後相對Java 8
所感受到的一些比較深入的進化,官方文檔裏說得也很是清楚了:https://docs.oracle.com/en/java/javase/11/
異步
我此次實驗裝的Java 11
版本是11.0.6
:函數式編程
下文將要實驗驗證的一些新特性其實也並不是Java 11
才引入,不少其實在Java 9
和Java 10
時就已經引入,只不過到了Java 11
這個穩定版才沉澱下來。
新版Java引入了一個全新的類型關鍵字var
,用var
來定義的變量不用寫具體類型,編譯器能根據=
右邊的實際賦值來自動推斷出變量的類型:函數
一、普通局部變量ui
var name = "codesheep"; // 自動推斷name爲String類型 System.out.println(name);
怎麼樣?是否是有一種在使用相似JavaScript這種弱類型語言的錯覺?
二、for循環中使用this
var upList1 = List.of( "劉能", "趙四", "謝廣坤" ); var upList2 = List.of( "永強", "玉田", "劉英" ); var upList3 = List.of( "謝飛機", "蘭妮", "蘭娜" ); var upListAll = List.of( upList1, upList2, upList3 ); for( var i : upListAll ) { // 用var接受局部變量的確很是簡潔! for( var j : i ) { System.out.println(j); } }
這地方就能看出用var
定義局部變量的優點了,假如這個例子中集合裏的元素類型更爲複雜,是相似List<List<String>>
這種嵌套類型的話,var
定義就很是簡潔明瞭!spa
三、固然,有些狀況是不能使用的
var
類型變量一旦賦值後,從新賦不一樣類型的值是不行的,好比:
var name = "codesheep"; name = 666; // 此時編譯會提示不兼容的類型
定義var
類型變量沒有初始化是不行的,好比:
var foo; // 此時編譯會提示沒法推斷類型 foo = "Foo";
另外,像類的成員變量類型
、方法入參類型
、返回值類型
等是不能使用var
的,好比:
public class Test { private var name; // 會提示不容許使用var public void setName( var name ) { // 會提示不容許使用var this.name = name; } public var getName() { // 會提示不容許使用var return name; } }
是的!
如今JDK
官方就自帶HTTP Client
了,位於java.net.http
包下,支持發送同步、異步的HTTP
請求,這樣一來,之前我們經常使用的HTTP請求客戶端諸如:OKHttp
、HttpClient
這種如今均可以退下了!
發送同步請求:
var request = HttpRequest.newBuilder() .uri( URI.create("https://www.codesheep.cn") ) .GET() .build(); // 同步請求方式,拿到結果前會阻塞當前線程 var httpResponse = HttpClient.newHttpClient() .send( request, HttpResponse.BodyHandlers.ofString()); System.out.println( httpResponse.body() ); // 打印獲取到的網頁內容
發送異步請求:
CompletableFuture<String> future = HttpClient.newHttpClient(). sendAsync( request, HttpResponse.BodyHandlers.ofString() ) .thenApply( HttpResponse::body ); System.out.println("我先繼續幹點別的事情..."); System.out.println( future.get() ); // 打印獲取到的網頁內容
固然你也能夠自定義請求頭,好比攜帶JWT Token
權限信息去請求等:
var requestWithAuth = HttpRequest.newBuilder() .uri( URI.create("http://www.xxxxxx.com/sth") ) .header("Authorization", "Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiIxNTIwNTE2MTE5NiIsImNyZWF0ZWQiOjE1ODMzMTA2ODk0MzYsImV4cCI6MTU4MzM5NzA4OSwidXNlcmlkIjoxMDAwNH0.OE9R5PxxsvtVJZn8ne-ksTb2aXXi7ipzuW9kbCiQ0uNoW0fJJr_wckLFmgDzxmBs3IdzIhWDAtaSIvmTshK_RQ") .GET() .build(); var response = HttpClient.newHttpClient() .send( requestWithAuth, HttpResponse.BodyHandlers.ofString() ); System.out.println( response.body() ); // 打印獲取到的接口返回內容
新版字符串String
類型增長了諸如:isBlank()
、strip()
、repeat()
等方便的字符串處理方法
String myName = " codesheep "; System.out.println( " ".isBlank() ); // 打印:true System.out.println( " ".isEmpty() ); // 打印:false System.out.println( myName.strip() ); // 打印codesheep,先後空格均移除 System.out.println( myName.stripLeading() ); // 打印codesheep ,僅頭部空格移除 System.out.println( myName.stripTrailing() ); // 打印 codesheep,僅尾部空格移除 System.out.println( myName.repeat(2) ); // 打印 codesheep codesheep
主要是增長了諸如of()
和copyOf()
等方法用於更加方便的建立和複製集合類型
var upList = List.of( "劉能", "趙四", "謝廣坤" ); var upListCopy = List.copyOf( upList ); System.out.println(upList); // 打印 [劉能, 趙四, 謝廣坤] System.out.println(upListCopy); // 打印 [劉能, 趙四, 謝廣坤] var upSet = Set.of("劉能","趙四"); var upSetCopy = Set.copyOf( upSet ); System.out.println(upSet); // 打印 [趙四, 劉能] System.out.println(upSetCopy); // 打印 [趙四, 劉能] var upMap = Map.of("劉能","58歲","趙四","59歲"); var upMapCopy = Map.copyOf( upMap ); System.out.println(upMap); // 打印 {劉能=58歲, 趙四=59歲} System.out.println(upMapCopy); // 打印 {劉能=58歲, 趙四=59歲}
我印象最深的是對Stream
流增長了諸如takeWhile()
和dropWhile()
的截止結算方法:
var upList = List.of( "劉能", "趙四", "謝廣坤" ); // 從集合中依次刪除知足條件的元素,直到不知足條件爲止 var upListSub1 = upList.stream() .dropWhile( item -> item.equals("劉能") ) .collect( Collectors.toList() ); System.out.println(upListSub1); // 打印 [趙四, 謝廣坤] // 從集合中依次獲取知足條件的元素,知道不知足條件爲止 var upListSub2 = upList.stream() .takeWhile( item -> item.equals("劉能") ) .collect( Collectors.toList() ); System.out.println( upListSub2 ); // 打印 [劉能]
一、Files類加強
咱們之前心心念的直接能把文件內容讀取到String
以及String
回寫到文件的功能終於支持了,能夠經過Files
類的靜態方法writeString()
和readString()
完成:
Path path = Paths.get("/Users/CodeSheep/test.txt"); String content = Files.readString(path, StandardCharsets.UTF_8); System.out.println(content); Files.writeString( path, "王老七", StandardCharsets.UTF_8 );
二、InputStream加強
InputStream
則增長了一個transferTo()
方法,直接將數據丟到OutputStream
去:
InputStream inputStream = new FileInputStream( "/Users/CodeSheep/test.txt" ); OutputStream outputStream = new FileOutputStream( "/Users/CodeSheep/test2.txt" ); inputStream.transferTo( outputStream );
好比我寫一個最簡單的Hello World
程序:
public class Hello { public static void main( String[] args ) { System.out.println("hello world"); } }
並保存爲hello.java
文件,這時候能夠直接用java
指令去運行這個Java源文件,直接省去之前javac
編譯源文件的過程:
java hello.java
怎麼樣?是否是和python源文件的運行有點像?這個信息量就有點大了,你們能夠自行腦補一下
Java 11確有不少改進,但仍是那句話,對於初學者來講Java 8了,不必刻意求新,穩纔是最重要的!