<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                # Java 9 特性和增強特性 > 原文: [https://howtodoinjava.com/java9/java9-new-features-enhancements/](https://howtodoinjava.com/java9/java9-new-features-enhancements/) Java 9 帶來了許多新的增強特性,它們將在很大程度上影響您的編程風格和習慣。 最大的變化是 Java 的模塊化。 這是 [Java 8](//howtodoinjava.com/java-8-tutorial/) 中的 [Lambdas](//howtodoinjava.com/java8/complete-lambda-expressions-tutorial-in-java/) 之后的又一重大變化。 在本文中,我列出了將作為 JDK 9 版本的一部分的更改。 ```java What is new in Java 9 Java platform module system Interface Private Methods HTTP 2 Client JShell - REPL Tool Platform and JVM Logging Process API Updates Collection API Updates Stream API Improvements Multi-Release JAR Files @Deprecated Tag Changes Stack Walking Java Docs Updates Miscellaneous Other Features ``` ## Java 平臺模塊系統 JPMS(Java 平臺模塊系統)是新 Java 9 版本的核心亮點。 它也被稱為 [Jigshaw 項目](https://openjdk.java.net/projects/jigsaw/)。 模塊是新的結構,就像我們已經有了包一樣。 使用新的模塊化編程開發的應用程序可以看作是交互模塊的集合,這些模塊之間具有明確定義的邊界和依賴性。 JPMS 包括為編寫模塊化應用程序以及模塊化 JDK 源代碼提供支持。 JDK 9 隨附約 92 個模塊(GA 版本中可能會進行更改)。 Java 9 模塊系統具有一個“`java.base`”模塊。 它被稱為基本模塊。 這是一個獨立模塊,不依賴于任何其他模塊。 默認情況下,所有其他模塊都依賴于“`java.base`”。 在 Java 模塊化編程中: 1. 模塊通常只是一個 jar 文件,其根目錄具有`module-info.class`文件。 2. 要使用模塊,請將 jar 文件而不是`classpath`包含在`modulepath`中。 添加到類路徑的模塊化 jar 文件是普通的 jar 文件,`module-info.class`文件將被忽略。 典型的`module-info.java`類如下所示: ```java module helloworld { exports com.howtodoinjava.demo; } module test { requires helloworld; } ``` > 閱讀更多: [Java 9 模塊教程](//howtodoinjava.com/java9/java-9-modules-tutorial/) ## 接口私有方法 Java 8 允許您在接口中編寫默認方法,這是廣受贊賞的特性。 因此,在此之后,接口僅缺少一些東西,只有非私有方法是其中之一。 從 Java 9 開始,您可以在接口中包含私有方法。 這些私有方法將改善接口內部的代碼可重用性。 舉例來說,如果需要兩個默認方法來共享代碼,則可以使用私有接口方法來共享代碼,但不必將該私有方法暴露給實現類。 在接口中使用私有方法有四個規則: 1. 接口私有方法不能是抽象的。 2. 私有方法只能在接口內部使用。 3. 私有靜態方法可以在其他靜態和非靜態接口方法中使用。 4. 私有非靜態方法不能在私有靜態方法內部使用。 在接口中使用私有方法的示例: ```java public interface CustomCalculator { default int addEvenNumbers(int... nums) { return add(n -> n % 2 == 0, nums); } default int addOddNumbers(int... nums) { return add(n -> n % 2 != 0, nums); } private int add(IntPredicate predicate, int... nums) { return IntStream.of(nums) .filter(predicate) .sum(); } } ``` > [Java 9 – 接口](//howtodoinjava.com/java9/java9-private-interface-methods/)中的私有方法 ## HTTP/2 客戶端 HTTP/1.1 客戶端于 1997 年發布。此后發生了很多變化。 因此,對于 Java 9,引入了新的 API,該 API 使用起來更加簡潔明了,并且還增加了對 HTTP/2 的支持。 新 API 使用 3 個主要類,即`HttpClient`,`HttpRequest`和`HttpResponse`。 要發出請求,就像獲取客戶,建立請求并發送它一樣簡單,如下所示。 ```java HttpClient httpClient = HttpClient.newHttpClient(); HttpRequest httpRequest = HttpRequest.newBuilder().uri(new URI("//howtodoinjava.com/")).GET().build(); HttpResponse<String> httpResponse = httpClient.send(httpRequest, HttpResponse.BodyHandler.asString()); System.out.println( httpResponse.body() ); ``` 上面的代碼看起來更簡潔易讀。 新 API 還使用`httpClient.sendAsync()`方法支持異步 HTTP 請求。 它返回`CompletableFuture`對象,該對象可用于確定請求是否已完成。 請求完成后,它還使您可以訪問`HttpResponse`。 最好的部分是,如果您愿意,甚至可以在請求完成之前取消它。 例如: ```java if(httpResponse.isDone()) { System.out.println(httpResponse.get().statusCode()); System.out.println(httpResponse.get().body()); } else { httpResponse.cancel(true); } ``` ## JShell – REPL 工具 **JShell** 是 **JDK 9** 發行版([JEP 222](https://openjdk.java.net/jeps/222))附帶的新命令行交互工具,用于求值用 Java 編寫的聲明,語句和表達式。 JShell 允許我們執行 Java 代碼段并獲得即時結果,而無需創建解決方案或項目。 Jshell 非常類似于 linux OS 中的命令窗口。 區別在于 JShell 是 Java 特定的。 除了執行簡單的代碼片段外,它還有許多其他特性。 例如 * 在單獨的窗口中啟動內置代碼編輯器 * 在單獨的窗口中啟動您選擇的代碼編輯器 * 在這些外部編輯器中發生“保存”操作時執行代碼 * 從文件系統加載預編寫的類 > [Java 9 JShell 教程](//howtodoinjava.com/java9/complete-jshell-tutorial-examples/) ## 平臺和 JVM 日志記錄 JDK 9 通過新的日志記錄 API 改進了平臺類(JDK 類)和 JVM 組件中的日志記錄。 它使您可以指定所選的日志記錄框架(例如 [Log4J2](//howtodoinjava.com/log4j2/))作為日志記錄后端,用于記錄來自 JDK 類的消息。 關于此 API,您應該了解幾件事: 1. 該 API 是由 JDK 中的類而非應用程序類使用的。 2. 對于您的應用程序代碼,您將像以前一樣繼續使用其他日志記錄 API。 3. 該 API 不允許您以編程方式配置記錄器。 該 API 包含以下內容: * 服務接口`java.lang.System.LoggerFinder`,它是抽象的靜態類 * 接口`java.lang.System.Logger`,它提供日志記錄 API * `java.lang.System`類中的重載方法`getLogger()`,它返回記錄器實例。 JDK 9 還添加了一個新的命令行選項`-Xlog`,使您可以單點訪問從 JVM 所有類記錄的所有消息。 以下是使用`-Xlog`選項的語法: ```java -Xlog[:][:[ <output>][:[<decorators>][:<output-options>]]]</output-options></decorators></output> ``` 所有選項都是可選的。 如果缺少`-Xlog`中的前一部分,則必須對該部分使用冒號。 例如,`-Xlog::stderr`表示所有部件均為默認設置,輸出設置為`stderr`。 我將在單獨的文章中深入討論該主題。 ## 進程 API 更新 在 Java 5 之前,產生新進程的唯一方法是使用`Runtime.getRuntime().exec()`方法。 然后在 Java 5 中,引入了`ProcessBuilder` API,該 API 支持一種更干凈的方式產生新進程。 現在,Java 9 添加了一種獲取有關當前進程和任何衍生進程的信息的新方法。 要獲取任何進程的信息,現在應該使用`java.lang.ProcessHandle.Info`接口。 此接口在獲取大量信息方面很有用,例如 * 用于啟動過程的命令 * 命令的參數 * 進程開始的瞬間 * 它和創建它的用戶所花費的總時間 ```java ProcessHandle processHandle = ProcessHandle.current(); ProcessHandle.Info processInfo = processHandle.info(); System.out.println( processHandle.getPid() ); System.out.println( processInfo.arguments().isPresent() ); System.out.println( pprocessInfo.command().isPresent() ); System.out.println( processInfo.command().get().contains("java") ); System.out.println( processInfo.startInstant().isPresent() ); ``` 要獲取新生成的進程的信息,請使用`process.toHandle()`方法獲取`ProcessHandle`實例。 其余的一切都如上所述。 ```java String javaPrompt = ProcessUtils.getJavaCmd().getAbsolutePath(); ProcessBuilder processBuilder = new ProcessBuilder(javaPrompt, "-version"); Process process = processBuilder.inheritIO().start(); ProcessHandle processHandle = process.toHandle(); ``` 也可以使用`ProcessHandle.allProcesses()`獲取系統中所有可用進程的`ProcessHandle`流。 要獲取所有子進程的列表(直接和深層次的子進程),請使用`children()`和`descendants()`方法。 ```java Stream<ProcessHandle> children = ProcessHandle.current().children(); Stream<ProcessHandle> descendants = ProcessHandle.current().descendants(); ``` ## 集合 API 更新 從 Java 9 開始,您可以使用新的工廠方法創建不可變集合,例如不可變列表,不可變集合和不可變映射。 例如 ```java import java.util.List; public class ImmutableCollections { public static void main(String[] args) { List<String> namesList = List.of("Lokesh", "Amit", "John"); Set<String> namesSet = Set.of("Lokesh", "Amit", "John"); Map<String, String> namesMap = Map.ofEntries( Map.entry("1", "Lokesh"), Map.entry("2", "Amit"), Map.entry("3", "Brian")); } } ``` > [Java 9 集合 API 的改進](//howtodoinjava.com/java9/create-immutable-collections-factory-methods/) ## 流 API 的改進 Java 9 引入了兩種與流進行交互的新方法,即`takeWhile`/`dropWhile`方法。 此外,它還添加了兩個重載方法,即`ofNullable`和`iterate`方法。 新方法`takeWhile`和`dropWhile`允許您基于謂詞獲取流的一部分。 1. 在有序流上,`takeWhile`返回流的“最長前綴”,其元素匹配給定謂詞。 `dropWhile`返回匹配給定謂詞的“最長前綴”之后的其余項。 2. 在無序流上,`takeWhile`返回流的子集,從流的開頭開始,其元素匹配給定謂詞(但不是全部)。 `dropWhile`返回不匹配給定謂詞的剩余的流元素。 同樣,在 Java 8 之前,流中不能具有`null`值。 會導致`NullPointerException`。 從 Java 9 開始,`Stream.ofNullable()`方法使您可以創建一個單元素流,如果不包含`null`,則包裝一個值,否則將為空流。 從技術上講,`Stream.ofNullable()`與流條件上下文中的空條件檢查非常相似。 > [Java 9 流 API 的改進](//howtodoinjava.com/java9/stream-api-improvements/) ## 多版本 JAR 文件 此增強與將應用程序類打包到 jar 文件中的方式有??關。 以前,您必須將所有類打包到一個 jar 文件中,并放到另一個要使用它的應用程序的類路徑中。 現在,通過使用多發行版特性,一個 jar 可以包含一個類的不同版本 – 與不同的 JDK 版本兼容。 有關類的不同版本以及通過加載的類應選擇哪個類的 JDK 版本的信息存儲在`MANIFEST.MF`文件中。 在這種情況下,`MANIFEST.MF`文件在其主要部分中包含條目`Multi-Release: true`。 此外,`META-INF`包含一個`versions`子目錄,該目錄的整數子目錄(從 Java 9 開始)存儲特定于版本的類和資源文件。 例如: ```java JAR content root A.class B.class C.class D.class META-INF MANIFEST.MF versions 9 A.class B.class ``` 假設在 JDK 10 中,`A.class`已更新為利用 Java 10 的某些特性,則可以如下所示更新此 Jar 文件: ```java JAR content root A.class B.class C.class D.class META-INF MANIFEST.MF versions 9 A.class B.class 10 A.class ``` 解決具有多種版本的 jar 彼此不兼容的大型應用程序中經常出現的依賴地獄,這看起來確實是很有前途的一步。 此特性可能對解決這些情況有很大幫助。 ## `@Deprecated`的標簽更改 從 Java 9 開始,[`@Deprecated`](http://download.java.net/java/jdk9/docs/api/java/lang/Deprecated.html)注解將具有兩個屬性,即`forRemoval`和`since`。 1. *`forRemoval`* – 指示帶注釋的元素是否在將來的版本中會被刪除。 2. *`since`* – 它返回已棄用帶注釋元素的版本。 強烈建議在文檔中使用`@deprecated` javadoc 標記說明不贊成使用程序元素的原因。 該文檔還應該建議并鏈接到建議的替代 API(如果適用)。 替換 API 的語義通常會有所不同,因此也應討論此類問題。 ## 棧的遍歷 棧是后進先出(LIFO)數據結構。 在 JVM 級別,棧存儲幀。 每次調用方法時,都會創建一個新框架并將其推入棧的頂部。 方法調用完成后,框架將被破壞(從棧中彈出)。 棧上的每個幀都包含其自己的局部變量數組,其自己的操作數棧,返回值以及對當前方法類的運行時常量池的引用。 在給定線程中,任何時候只有一幀處于活動狀態。 活動幀稱為當前幀,其方法稱為當前方法。([閱讀更多](https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.5.2)) 直到 Java 8,`StackTraceElement`代表一個棧幀。 要獲得完整的棧,您必須使用`Thread.getStackTrace()`和`Throwable.getStackTrace()`。 它返回了`StackTraceElement`數組,您可以對其進行迭代以獲取所需的信息。 在 Java 9 中,引入了新類`StackWalker`。 該類使用當前線程的棧幀順序流提供簡單有效的棧遍歷。 `StackWalker`類非常有效,因為它懶惰地求值棧幀。 ```java // Prints the details of all stack frames of the current thread StackWalker.getInstance().forEach(System.out::println); ``` 您可以使用此信息流執行其他許多操作,我們將在其他一些專用文章中介紹這些內容。 ## Java 文檔更新 Java 9 增強了`javadoc`工具以生成 HTML5 標記。 當前,它以 HTML 4.01 生成頁面。 為了生成 HTML5 Javadoc,需要在命令行參數中加入參數`-html5`。 要在命令行上生成文檔,可以運行: ```java javadoc [options] [packagenames] [sourcefiles] [@files] ``` 使用 HTML5 可以帶來更輕松的 HTML5 結構的好處。 它還實現了 [WAI-ARIA 標準](https://www.w3.org/WAI/intro/aria)的可訪問性。 這樣做的目的是使身體或視覺障礙的人更容易使用屏幕閱讀器等工具訪問 javadocs 頁面。 [JEP 225](https://openjdk.java.net/jeps/225) 提供了在 Javadoc 中搜索程序元素以及標記的單詞和短語的特性。 以下內容將被索引并可以搜索: * 聲明的模塊名稱 * 配套 * 類型和成員 * 方法參數類型的簡單名稱 這是通過新的`search.js` Javascript 文件以及在生成 Javadoc 時生成的索引在客戶端實現的。 在生成的 HTML5 API 頁面上有一個搜索框。 請注意,默認情況下將添加“搜索”選項,但可以使用參數`-noindex`將其關閉。 ## 其他特性 Java 9 中還有其他特性,我在這里列出以供快速參考。 我們將在以后的文章中討論所有這些特性。 * 反應式流 API * GC(垃圾收集器)改進 * 篩選傳入的序列化數據 * 棄用 Applet API * 字符串化連接 * 增強的方法句柄 * 精簡字符串 * Nashorn 的解析器 API Java 9 計劃于 2017/09/21 發行。 對于最新更改,請遵循此[鏈接](https://openjdk.java.net/projects/jdk9/)。 學習愉快!
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看