2018年9月26日,Oracle 官方宣布 Java 11 正式发布,这是自 Java8 之后 Java 大版本周期变化后的第一个长期支持版本。这篇介绍的是 Java9 到 Java11 累积的一些新特性,只涉及语法和编码上的功能,其他的如工具和虚拟机改进不涉及。
本文源码地址:code-note 
1. 接口 接口允许有私有方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 interface  Enhance  {    default  void  defaultMethod ()  {         init();     }     private  void  init ()  {         staticMethod();     }     static  void  staticMethod ()  {         System.out.println("static method in interface." );     } } 
 
2. try 语句 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 @Test public  void  tryTest ()  {    String  path  =  "/home/nathan/test.sh" ;          try  (var  reader  =  new  InputStreamReader (System.in)) {     } catch  (IOException e) {         e.printStackTrace();     }          var  reader  =  new  InputStreamReader (System.in);     var  writer  =  new  OutputStreamWriter (System.out);     try  (reader; writer) {              } catch  (IOException e) {         e.printStackTrace();     } } 
 
3. I/O 流新特性 类 java.io.InputStream 中增加了新的方法来读取和复制 InputStream 中包含的数据。 
readAllBytes:读取 InputStream 中的所有剩余字节。  
readNBytes: 从 InputStream 中读取指定数量的字节到数组中。  
transferTo:读取 InputStream 中的全部字节并写入到指定的 OutputStream 中。 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 @Test public  void  InputStreamTest ()  throws  IOException {    InputStream  inputStream  =  EnhanceExample.class.getResourceAsStream("test.txt" );     byte [] arr = new  byte [5 ];     inputStream.readNBytes(arr, 0 , 5 );     Assert.assertEquals("Java9" , new  String (arr));     byte [] allBytes = inputStream.readAllBytes();     Assert.assertEquals("Java10Java11" , new  String (allBytes));     InputStream  inputStream1  =  EnhanceExample.class.getResourceAsStream("test.txt" );;     ByteArrayOutputStream  outputStream  =  new  ByteArrayOutputStream ();     inputStream1.transferTo(outputStream);     Assert.assertEquals("Java9Java10Java11" , outputStream.toString()); } 
 
4. 集合、Stream 和 Optional 在集合框架中,Java 9 增加 了 List.of()、Set.of()、Map.of() 和 Map.ofEntries() 等工厂方法来创建不可变集合
1 2 3 4 5 6 @Test public  void  unmodifiableCollectionTest ()  {    List<Integer> integers = List.of(1 , 2 , 3 );     Set<String> strings = Set.of("a" , "b" , "c" );     Map<String, Integer> stringIntegerMap = Map.of("a" , 1 , "b" , 2 , "c" , 3 ); } 
 
Stream 中增加了新的方法 ofNullable、dropWhile、takeWhile 和 iterate;Collectors 中增加了新的方法 filtering 和 flatMapping。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 @Test public  void  streamTest ()  {    List<Integer> list = Arrays.asList(1 , 2 , 4 , 5 , 3 , 2 , 8 );          list.stream().takeWhile(x -> x < 5 ).forEach(System.out::println);          List<Integer> collect = Stream.of(1 , 2 , 3 , 4 , 5 ).dropWhile(i -> i%3 !=0 ).collect(Collectors.toList());     System.out.println(collect);          Stream<Object> stream = Stream.ofNullable(null );          long  count  =  Stream.of(             Optional.of(1 ),             Optional.empty(),             Optional.of(2 )).flatMap(Optional::stream).count();     Assert.assertEquals(2 , count);          Optional.empty().orElseThrow(); } 
 
Stream 还提供一个 Predicate (判断条件)来指定什么时候结束迭代。
1 2 3 4 5 6 @Test public  void  iterateTest ()  {    Stream.iterate(1 , i -> ++i).limit(5 ).forEach(System.out::println);          Stream.iterate(1 , i -> i <= 5 , i -> ++i).forEach(System.out::println); } 
 
5. 变量类型推断 从 Java10 开始变量不需要写具体类型,变量类型直接使用 var 定义,编译器能根据右边的表达式自动推断类型。
1 2 3 4 5 6 @Test public  void  var ()  {    String  str1  =  "abc" ;     var  str2  =  "abc" ;     Assert.assertEquals(str1, str2); } 
 
对象引用也可以使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @Test public  void  collection ()  {         var  list  =  new  ArrayList <>();     list.add(123 );     list.add("abc" );          var  v  =  new  VariableTest ();     System.out.println(v.getClass().getName());     Runnable  runnable  =  () -> System.out.println("interface var" );           } 
 
6. HTTP 客户端 Java 11 对 Java 9 中引入并在 Java 10 中进行了更新的 Http Client API 进行了标准化,Java 11 中的新 Http Client API,提供了对 HTTP/2 等业界前沿标准的支持,同时也向下兼容 HTTP/1.1,精简而又友好的 API 接口,与主流开源 API(如:Apache HttpClient、Jetty、OkHttp 等)类似甚至拥有更高的性能。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 import  org.junit.Before;import  org.junit.Test;import  java.io.IOException;import  java.net.*;import  java.net.http.HttpClient;import  java.net.http.HttpRequest;import  java.net.http.HttpResponse;import  java.time.Duration;public  class  HttpClientExample  {    HttpClient client;     @Before      public  void  init ()  {         client = HttpClient.newBuilder().connectTimeout(Duration.ofMillis(20000L )).build();     }     @Test      public  void  reqTest ()  throws  IOException, InterruptedException {         var  request  =  HttpRequest.newBuilder(URI.create("https://zguishen.com/" )).build();                  String  body  =  client.send(request, HttpResponse.BodyHandlers.ofString()).body();         System.out.println(body);     }          @Test      public  void  getTest ()  {         var  request  =  HttpRequest.newBuilder()                 .uri(URI.create("https://api.github.com/users/zgshen" ))                 .header("Accept" , "application/vnd.github.v3+json" )                                  .timeout(Duration.ofSeconds(10000L ))                 .GET()                 .build();         client.sendAsync(request, HttpResponse.BodyHandlers.ofString())                 .whenCompleteAsync((res, exp) -> {                     System.out.println(res.body());                 }).join();     }          @Test      public  void  postTest ()  {         var  requestBody  =  "{'key':'val'}" ;         var  request  =  HttpRequest.newBuilder()                 .uri(URI.create("http://example.com/json" ))                 .header("Contend-Type" ,"application/json" )                 .timeout(Duration.ofSeconds(10000L ))                 .POST(HttpRequest.BodyPublishers.ofString(requestBody))                 .build();         client.sendAsync(request, HttpResponse.BodyHandlers.ofString())                 .whenCompleteAsync((res, exp) -> {                     System.out.println(res.body());                 }).join();     }          @Test      public  void  Http2Test ()  throws  URISyntaxException {         HttpClient.newBuilder()                 .followRedirects(HttpClient.Redirect.NEVER)                 .version(HttpClient.Version.HTTP_2)                 .build()                 .sendAsync(HttpRequest.newBuilder()                                 .uri(new  URI ("https://zguishen.com/" ))                                 .GET()                                 .build(),                         HttpResponse.BodyHandlers.ofString())                 .whenComplete((resp, t) -> {                     if  (t != null ) {                         t.printStackTrace();                     } else  {                         System.out.println(resp.version());                         System.out.println(resp.statusCode());                     }                 }).join();     } } 
 
7. 参考