<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>

          300 秒快速了解 Java 9 - 16 新特性,助你脫離內(nèi)卷

          共 9647字,需瀏覽 20分鐘

           ·

          2021-08-09 22:34

          作者 | 空無

          來源 | https://juejin.cn/post/6964543834747322405

          點贊再看,養(yǎ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 的主要新特性,早學完早下班!

          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<Integer> numbers = new ArrayList<>();

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

          List<Integer> 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());
          }

          JAVA 10(2018年3月)

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

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

          var message = "Hello, Java 10";

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

          JAVA 11(2018年9月)

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

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

          List<String> 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 這下也可以用這個功能,真香!

          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();
          }

          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"
              }
              """;

          JAVA 14(2020年3月)

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

          一般我們創(chuàng)建一個 POJO 類,需要定義屬性列表,構造函數(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 "main" java.lang.NullPointerException: Cannot 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.classByteOrder.nativeOrder());
          varHandle.set(memoryAddress, value);

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

          不了解 Unsafe 操作堆外內(nèi)存方式的同學,可以參考我的另一篇文章《JDK中為了性能大量使用的Unsafe類,你會用嗎?》

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

          之前如果想構建一個可執(zhí)行的程序,還需要借助三方工具,將 JRE 一起打包,或者讓客戶電腦也裝一個 JRE 才可以運行我們的 JAVA 程序。

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

          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;
              }

          }

          JAVA 16(2021年3月)

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

          總結

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

          看看時間,300 秒到了嗎?

          - END -

          往期推薦

          阿里新瓜!又一個衣冠禽獸?

          戰(zhàn)爭升級!Elasticsearch 從客戶端向 AWS 開了一炮!

          騰訊員工吐槽:團隊來了個阿里高p,瞬間會議變多,群多了

          程序員加入新團隊必問的20道問題

          只是想虐下春麗,一不小心擼了臺游戲機...



          喜歡本文歡迎轉(zhuǎn)發(fā),關注我訂閱更多精彩

          關注我回復「加群」,加入Spring技術交流群

          瀏覽 52
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

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

          手機掃一掃分享

          分享
          舉報
          <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>
                  成年人毛片国产网站国产片 | 麻豆91网站 | 日本sm视频 | 在线观看污网站 | 69免费观看视频 |