<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          用著 JDK8 卻寫著 JDK6 的代碼,是你嗎

          共 9302字,需瀏覽 19分鐘

           ·

          2021-08-09 01:59

          有多少小伙伴在用著 JDK8 卻寫著 JDK6 的代碼,最近在連載 WebFlux,深感 JDK8 中的 Lambda、函數(shù)式接口,JDK9 中的 FlowAPI 的重要,因此一直想整篇文章和大家梳理下從 JDK8 開始 Java 的一些變化,剛好最近在網(wǎng)上看到這篇文章,就順手和大家分享下。


          JAVA 這幾年的更新實在是太太太……快了,JAVA 8 都還沒用多久,16 都已經(jīng)發(fā)布了。自從 JAVA 8 發(fā)布了 Lambda 和 Stream 之后,JAVA 就像打了雞血一樣,半年一個版本的發(fā)布,生產(chǎn)隊的驢也沒這么勤快。



          導致我們現(xiàn)在完全跟不上 JAVA 發(fā)布的節(jié)奏,我司目前還停留在 JAVA 8,甚至部分老系統(tǒng)還在使用 JAVA 7,根本不能輕易的升級。


          雖然暫時用不上最新版本的 JAVA,但了解每個新版本的主要特性還是很重要的,不然哪天真跟著升級了,那還不得一臉懵逼。


          本文就帶你快速了解 JAVA 9 - 16 的主要新特性!

           

          1

          JAVA 9(2017年9月)

           

          接口里可以添加私有接口


          JAVA 8 對接口增加了默認方法的支持,在 JAVA 9 中對該功能又來了一次升級,現(xiàn)在可以在接口里定義私有方法,然后在默認方法里調(diào)用接口的私有方法。


          這樣一來,既可以重用私有方法里的代碼,又可以不公開代碼


          public interface TestInterface {
              default void wrapMethod(){
                  innerMethod();
              }

              private void innerMethod(){
                  System.out.println("");
              }
          }


          匿名內(nèi)部類也支持鉆石(diamond)運算符


          JAVA 5 就引入了泛型(generic),到了 JAVA 7 開始支持鉆石(diamond)運算符:<>,可以自動推斷泛型的類型:


          List numbers = new ArrayList<>();


          但是這個自動推斷類型的鉆石運算符可不支持匿名內(nèi)部類,在 JAVA 9 中也對匿名內(nèi)部類做了支持:


          List numbers = new ArrayList<>() {
              ...
          }


          增強的 try-with-resources


          JAVA 7 中增加了try-with-resources的支持,可以自動關閉資源:


          try (BufferedReader bufferReader = new BufferedReader(...)) {
              return bufferReader.readLine();
          }


          但需要聲明多個資源變量時,代碼看著就有點惡心了,需要在 try 中寫多個變量的創(chuàng)建過程:


          try (BufferedReader bufferReader0 = new BufferedReader(...);
              BufferedReader bufferReader1 = new BufferedReader(...)) {
              return bufferReader0.readLine();
          }


          JAVA 9 中對這個功能進行了增強,可以引用 try 代碼塊之外的變量來自動關閉:


          BufferedReader bufferReader0 = new BufferedReader(...);
          BufferedReader bufferReader1 = new BufferedReader(...);
          try (bufferReader0; bufferReader1) {
              System.out.println(br1.readLine() + br2.readLine());
          }


           

          2

          JAVA 10(2018年3月)


          局部變量的自動類型推斷(var)


          JAVA 10 帶來了一個很有意思的語法 - var,它可以自動推斷局部變量的類型,以后再也不用寫類型了,也不用靠 lombok 的 var 注解增強了


          var message = "Hello, Java 10";


          不過這個只是語法糖,編譯后變量還是有類型的,使用時還是考慮下可維護性的問題,不然寫多了可就成 JavaScript 風格了

           


          3

          JAVA 11(2018年9月)

           

          Lambda 中的自動類型推斷(var)


          JAVA 11 中對 Lambda 語法也支持了 var 這個自動類型推斷的變量,通過 var 變量還可以增加額外的注解:


          List languages = Arrays.asList("Java""Groovy");
          String language = sampleList.stream()
            .map((@Nonnull var x) -> x.toUpperCase())
            .collect(Collectors.joining(", "));

          assertThat(language).isEqualTo("Java, Groovy");


          javac + java 命令一把梭


          以前編譯一個 java 文件時,需要先 javac 編譯為 class,然后再用 java 執(zhí)行,現(xiàn)在可以一把梭了:


          $ java HelloWorld.java
          Hello Java 11!


          Java Flight Recorder 登陸 OpenJDK


          Java Flight Recorder 是個灰常好用的調(diào)試診斷工具,不過之前是在 Oracle JDK 中,也跟著 JDK 11 開源了,OpenJDK 這下也可以用這個功能,真香!另外,關注我們,公號終碼一生,后臺回復“資料”,獲取相關視頻和最新面試資料。


           

          4

          JAVA 12(2019年3月)

           

          更簡潔的 switch 語法


          在之前的 JAVA 版本中,switch 語法還是比較啰嗦的,如果多個值走一個邏輯需要寫多個 case:


          DayOfWeek dayOfWeek = LocalDate.now().getDayOfWeek();
          String typeOfDay = "";
          switch (dayOfWeek) {
              case MONDAY:
              case TUESDAY:
              case WEDNESDAY:
              case THURSDAY:
              case FRIDAY:
                  typeOfDay = "Working Day";
                  break;
              case SATURDAY:
              case SUNDAY:
                  typeOfDay = "Day Off";
          }


          到了 JAVA 12,這個事情就變得很簡單了,幾行搞定,而且!還支持返回值:


          typeOfDay = switch (dayOfWeek) {
              case MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY -> "Working Day";
              case SATURDAY, SUNDAY -> "Day Off";
          };


          instanceof + 類型強轉(zhuǎn)一步到位


          之前處理動態(tài)類型碰上要強轉(zhuǎn)時,需要先 instanceof 判斷一下,然后再強轉(zhuǎn)為該類型處理:


          Object obj = "Hello Java 12!";
          if (obj instanceof String) {
              String s = (String) obj;
              int length = s.length();
          }


          現(xiàn)在 instanceof 支持直接類型轉(zhuǎn)換了,不需要再來一次額外的強轉(zhuǎn):


          Object obj = "Hello Java 12!";
          if (obj instanceof String str) {
              int length = str.length();
          }


           

          5

          JAVA 13(2019年9月)

           

          switch 語法再增強


          JAVA 12 中雖然增強了 swtich 語法,但并不能在 -> 之后寫復雜的邏輯,JAVA 12 帶來了 swtich更完美的體驗,就像 lambda 一樣,可以寫邏輯,然后再返回:


          typeOfDay = switch (dayOfWeek) {
              case MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY -> {
                  // do sth...
                  yield "Working Day";
              }
              case SATURDAY, SUNDAY -> "Day Off";
          };


          文本塊(Text Block)的支持

          你是否還在為大段帶換行符的字符串報文所困擾,換行吧一堆換行符,不換行吧看著又難受:


          String json = "{\"id\":\"1697301681936888\",\"nickname\":\"空無\",\"homepage\":\"https://juejin.cn/user/1697301681936888\"}";


          JAVA 13 中幫你解決了這個惡心的問題,增加了文本塊的支持,現(xiàn)在可以開心的換行拼字符串了,就像用模板一樣:


          String json = """
                          {
                              "id":"1697301681936888",
                              "nickname":"空無",
                              "homepage":"https://juejin.cn/user/1697301681936888"
                          }
                          """;


           

          6

          JAVA 14(2020年3月)


          新增的 record 類型,干掉復雜的 POJO 類


          一般我們創(chuàng)建一個 POJO 類,需要定義屬性列表,構(gòu)造函數(shù),getter/setter,比較麻煩。JAVA 14 為我們帶來了一個便捷的創(chuàng)建類的方式 - record


          public record UserDTO(String id,String nickname,String homepage{ };

          public static void main( String[] args ){
              UserDTO user = new UserDTO("1697301681936888","空無","https://juejin.cn/user/1697301681936888");
              System.out.println(user.id);
              System.out.println(user.nickname);
              System.out.println(user.id);
          }


          IDEA 也早已支持了這個功能,創(chuàng)建類的時候直接就可以選:



          不過這個只是一個語法糖,編譯后還是一個 Class,和普通的 Class 區(qū)別不大


          更直觀的 NullPointerException 提示


          NullPointerException 算是 JAVA 里最常見的一個異常了,但這玩意提示實在不友好,遇到一些長一點的鏈式表達式時,沒辦法分辨到底是哪個對象為空。


          比如下面這個例子中,到底是 innerMap 為空呢,還是 effected 為空呢?


          Map<String,Map<String,Boolean>> wrapMap = new HashMap<>();
          wrapMap.put("innerMap",new HashMap<>());
          boolean effected = wrapMap.get("innerMap").get("effected");
          // StackTrace:
          Exception in thread "main" java.lang.NullPointerException
              at org.example.App.main(App.java:50)


          JAVA 14 也 get 到了 JAVAER 們的痛點,優(yōu)化了 NullPointerException 的提示,讓你不在困惑,一眼就能定位到底“空”在哪!


          Exception in thread "mainjava.lang.NullPointerExceptionCannot invoke "java.lang.Boolean.booleanValue()" because the return value of "java.util.Map.get(Object)" is null
              at org.example.App.main(App.java:50)


          現(xiàn)在的 StackTrace 就很直觀了,直接告訴你 effected 變量為空,再也不用困惑!


          安全的堆外內(nèi)存讀寫接口,別再玩 Unsafe 的騷操作了


          在之前的版本中,JAVA 如果想操作堆外內(nèi)存(DirectBuffer),還得 Unsafe 各種 copy/get/offset。現(xiàn)在直接增加了一套安全的堆外內(nèi)存訪問接口,可以輕松的訪問堆外內(nèi)存,再也不用搞 Unsafe 的騷操作了。


          // 分配 200B 堆外內(nèi)存
          MemorySegment memorySegment = MemorySegment.allocateNative(200);

          // 用 ByteBuffer 分配,然后包裝為 MemorySegment
          MemorySegment memorySegment = MemorySegment.ofByteBuffer(ByteBuffer.allocateDirect(200));

          // MMAP 當然也可以
          MemorySegment memorySegment = MemorySegment.mapFromPath(
            Path.of("/tmp/memory.txt"), 200, FileChannel.MapMode.READ_WRITE);

          // 獲取堆外內(nèi)存地址
          MemoryAddress address = MemorySegment.allocateNative(100).baseAddress();

          // 組合拳,堆外分配,堆外賦值
          long value = 10;
          MemoryAddress memoryAddress = MemorySegment.allocateNative(8).baseAddress();

          // 獲取句柄
          VarHandle varHandle = MemoryHandles.varHandle(long.class, ByteOrder.nativeOrder());

          varHandle.set(memoryAddress, value);
          // 釋放就這么簡單,想想 DirectByteBuffer 的釋放……多奇怪
          memorySegment.close();


          新增的 jpackage 打包工具,直接打包二進制程序,再也不用裝 JRE 了


          之前如果想構(gòu)建一個可執(zhí)行的程序,還需要借助三方工具,將 JRE 一起打包,或者讓客戶電腦也裝一個 JRE 才可以運行我們的 JAVA 程序。另外,關注我們,公號終碼一生,后臺回復“資料”,獲取相關視頻和最新面試資料。


          現(xiàn)在 JAVA 直接內(nèi)置了 jpackage 打包工具,幫助你一鍵打包二進制程序包,終于不用亂折騰了

           


          7

          JAVA 15(2020年9月)


          ZGC 和 Shenandoah 兩款垃圾回收器正式登陸


          在 JAVA 15中,ZGC 和 Shenandoah 再也不是實驗功能,正式登陸了(不過 G1 仍然是默認的)。如果你升級到 JAVA 15 以后的版本,就趕快試試吧,性能更強,延遲更低


          封閉(Sealed )類


          JAVA 的繼承目前只能選擇允許繼承和不允許繼承(final 修飾),現(xiàn)在新增了一個封閉(Sealed )類的特性,可以指定某些類才可以繼承:


          public sealed interface Service permits CarTruck {
              int getMaxServiceIntervalInMonths();
              default int getMaxDistanceBetweenServicesInKilometers() {
                  return 100000;
              }
          }



          8

          JAVA 16(2021年3月)


          JAVA 16 在用戶可見的地方變化并不多,基本都是 14/15 的實驗性內(nèi)容,到了 16 正式發(fā)布,這里就不重復介紹了。



          9

          總結(jié)

           

          以上介紹的各種新特性,有些特性在歷史版本中還屬于實驗性功能,不過按照 JAVA 目前這個驢一樣的更新頻率,很可能下個版本就是穩(wěn)定版了。早學早享受,晚學被卷走…


          文章鏈接:juejin.cn/post/6964543834747322405


          瀏覽 38
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  人人舔人人操人人干 | 麻豆传媒在线看免费版高清视频 | 高清无码在线免费观看 | 免费看毛片网站 | 1000色看免费 |