更新時(shí)間:2022-10-14 09:58:02 來(lái)源:動(dòng)力節(jié)點(diǎn) 瀏覽1882次
Java 9 帶有豐富的特性集。雖然沒有新的語(yǔ)言概念,但新的 API 和診斷命令肯定會(huì)引起開發(fā)人員的興趣。
在這篇文章中,我們將對(duì)一些新功能進(jìn)行快速、高級(jí)的了解;此處提供了新功能的完整列表。
讓我們從最重要的開始——將模塊化引入 Java 平臺(tái)。
模塊化系統(tǒng)提供類似于 OSGi 框架系統(tǒng)的功能。模塊具有依賴關(guān)系的概念,可以導(dǎo)出公共 API 并將實(shí)現(xiàn)細(xì)節(jié)隱藏/私有。
這里的主要?jiǎng)訖C(jī)之一是提供模塊化 JVM,它可以在可用內(nèi)存少得多的設(shè)備上運(yùn)行。JVM 只能使用應(yīng)用程序所需的那些模塊和 API 運(yùn)行。查看此鏈接以了解這些模塊是什么。
此外,無(wú)法再?gòu)膽?yīng)用程序代碼訪問com.sun.*等 JVM 內(nèi)部(實(shí)現(xiàn))API 。
簡(jiǎn)而言之,這些模塊將在位于 java 代碼層次結(jié)構(gòu)頂部的名為module-info.java的文件中進(jìn)行描述:
module com.baeldung.java9.modules.car {
requires com.baeldung.java9.modules.engines;
exports com.baeldung.java9.modules.car.handling;
}
我們的模塊車需要模塊引擎來(lái)運(yùn)行并導(dǎo)出一個(gè)包進(jìn)行處理。
期待已久的舊HttpURLConnection替代品。
新 API 位于java.net.http包下。
它應(yīng)該支持HTTP/2 協(xié)議和WebSocket握手,其性能應(yīng)該可以與Apache HttpClient、Netty和Jetty相媲美。
讓我們通過創(chuàng)建和發(fā)送一個(gè)簡(jiǎn)單的 HTTP 請(qǐng)求來(lái)看看這個(gè)新功能。
更新:HTTP 客戶端 JEP正在移至 Incubator 模塊,因此它不再在包java.net.http中可用,而是在jdk.incubator.http 下可用。
快速獲取請(qǐng)求
API 使用 Builder 模式,這使得快速使用變得非常容易:
HttpRequest request = HttpRequest.newBuilder()
.uri(new URI("https://postman-echo.com/get"))
.GET()
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandler.asString());
進(jìn)程 API 已針對(duì)控制和管理操作系統(tǒng)進(jìn)程進(jìn)行了改進(jìn)。
(1)處理信息
java.lang.ProcessHandle類包含大部分新功能:
ProcessHandle self = ProcessHandle.current();
long PID = self.getPid();
ProcessHandle.Info procInfo = self.info();
Optional<String[]> args = procInfo.arguments();
Optional<String> cmd = procInfo.commandLine();
Optional<Instant> startTime = procInfo.startInstant();
Optional<Duration> cpuUsage = procInfo.totalCpuDuration();
current方法返回一個(gè)對(duì)象,表示當(dāng)前正在運(yùn)行的 JVM 的進(jìn)程。Info子類提供有關(guān)該過程的詳細(xì)信息。
(2)銷毀進(jìn)程
現(xiàn)在 - 讓我們使用destroy()停止所有正在運(yùn)行的子進(jìn)程:
childProc = ProcessHandle.current().children();
childProc.forEach(procHandle -> {
assertTrue("Could not kill process " + procHandle.getPid(), procHandle.destroy());
});
(1)試用資源
在 Java 7 中,try-with-resources語(yǔ)法要求為語(yǔ)句管理的每個(gè)資源聲明一個(gè)新變量。
在 Java 9 中還有一個(gè)額外的改進(jìn):如果資源被 final 或有效的 final 變量引用,則 try-with-resources 語(yǔ)句可以在不聲明新變量的情況下管理資源:
MyAutoCloseable mac = new MyAutoCloseable();
try (mac) {
// do some stuff with mac
}
try (new MyAutoCloseable() { }.finalWrapper.finalCloseable) {
// do some stuff with finalCloseable
} catch (Exception ex) { }
(2)鉆石運(yùn)算符擴(kuò)展
現(xiàn)在我們可以將菱形運(yùn)算符與匿名內(nèi)部類結(jié)合使用:
FooClass<Integer> fc = new FooClass<>(1) { // anonymous inner class
};
FooClass<? extends Integer> fc0 = new FooClass<>(1) {
// anonymous inner class
};
FooClass<?> fc1 = new FooClass<>(1) { // anonymous inner class
};
(3)接口私有方法
即將發(fā)布的 JVM 版本中的接口可以具有私有方法,可用于拆分冗長(zhǎng)的默認(rèn)方法:
interface InterfaceWithPrivateMethods {
private static String staticPrivate() {
return "static private";
}
private String instancePrivate() {
return "instance private";
}
default void check() {
String result = staticPrivate();
InterfaceWithPrivateMethods pvt = new InterfaceWithPrivateMethods() {
// anonymous class
};
result = pvt.instancePrivate();
}
}}
JShell 是 read-eval-print 循環(huán)——簡(jiǎn)稱 REPL。
簡(jiǎn)而言之,它是一個(gè)交互式工具,用于評(píng)估 Java 的聲明、語(yǔ)句和表達(dá)式,以及一個(gè) API。測(cè)試小代碼片段非常方便,否則需要使用main方法創(chuàng)建一個(gè)新類。
jshell可執(zhí)行文件本身可以在<JAVA_HOME>/bin文件夾中找到:
jdk-9\bin>jshell.exe
| Welcome to JShell -- Version 9
| For an introduction type: /help intro
jshell> "This is my long string. I want a part of it".substring(8,19);
$5 ==> "my long string"
交互式外殼帶有歷史記錄和自動(dòng)完成功能;它還提供諸如保存和加載文件、所有或部分書面語(yǔ)句的功能:
jshell> /save c:\develop\JShell_hello_world.txt
jshell> /open c:\develop\JShell_hello_world.txt
Hello JShell!
代碼片段在文件加載時(shí)執(zhí)行。
讓我們探索jcmd命令行實(shí)用程序中的一些新子命令。我們將獲得 JVM 中加載的所有類及其繼承結(jié)構(gòu)的列表。
在下面的示例中,我們可以看到運(yùn)行 Eclipse Neon 的 JVM 中加載的java.lang.Socket的層次結(jié)構(gòu):
jdk-9\bin>jcmd 14056 VM.class_hierarchy -i -s java.net.Socket
14056:
java.lang.Object/null
|--java.net.Socket/null
| implements java.io.Closeable/null (declared intf)
| implements java.lang.AutoCloseable/null (inherited intf)
| |--org.eclipse.ecf.internal.provider.filetransfer.httpclient4.CloseMonitoringSocket
| | implements java.lang.AutoCloseable/null (inherited intf)
| | implements java.io.Closeable/null (inherited intf)
| |--javax.net.ssl.SSLSocket/null
| | implements java.lang.AutoCloseable/null (inherited intf)
| | implements java.io.Closeable/null (inherited intf)
jcmd命令的第一個(gè)參數(shù)是我們要在其上運(yùn)行命令的 JVM 的進(jìn)程 ID (PID)。
另一個(gè)有趣的子命令是set_vmflag。我們可以在線修改一些JVM參數(shù),而不需要重啟JVM進(jìn)程和修改它的啟動(dòng)參數(shù)。
您可以使用子命令jcmd 14056 VM.flags -all找出所有可用的 VM 標(biāo)志
接口java.awt.image.MultiResolutionImage將一組具有不同分辨率的圖像封裝到一個(gè)對(duì)象中。我們可以根據(jù)給定的 DPI 指標(biāo)和圖像轉(zhuǎn)換集檢索特定于分辨率的圖像變體,或者檢索圖像中的所有變體。
java.awt.Graphics類根據(jù)當(dāng)前顯示 DPI 指標(biāo)和任何應(yīng)用的轉(zhuǎn)換從多分辨率圖像中獲取變體。
java.awt.image.BaseMultiResolutionImage類提供了基本實(shí)現(xiàn):
BufferedImage[] resolutionVariants = ....
MultiResolutionImage bmrImage
= new BaseMultiResolutionImage(baseIndex, resolutionVariants);
Image testRVImage = bmrImage.getResolutionVariant(16, 16);
assertSame("Images should be the same", testRVImage, resolutionVariants[3]);
API 位于java.lang.invoke下,由VarHandle和MethodHandles組成。它在對(duì)象字段和數(shù)組元素上提供等效的java.util.concurrent.atomic和sun.misc.Unsafe操作,具有相似的性能。
使用 Java 9 Modular 系統(tǒng)將無(wú)法從應(yīng)用程序代碼訪問sun.misc.Unsafe 。
java.util.concurrent.Flow類提供了支持Reactive Streams發(fā)布-訂閱框架的接口。這些接口支持跨在 JVM 上運(yùn)行的多個(gè)異步系統(tǒng)的互操作性。
我們可以使用實(shí)用程序類SubmissionPublisher來(lái)創(chuàng)建自定義組件。
此功能為 JVM 的所有組件引入了一個(gè)通用的日志記錄系統(tǒng)。它提供了進(jìn)行日志記錄的基礎(chǔ)設(shè)施,但它沒有添加來(lái)自所有 JVM 組件的實(shí)際日志記錄調(diào)用。它也不向 JDK 中的 Java 代碼添加日志記錄。
日志框架定義了一組標(biāo)簽——例如gc、編譯器、線程等。我們可以使用命令行參數(shù)-Xlog在啟動(dòng)期間打開日志。
讓我們使用'debug'級(jí)別將帶有'gc'標(biāo)簽的消息記錄到一個(gè)名為'gc.txt'的文件中,沒有任何修飾:
java -Xlog:gc=debug:file=gc.txt:none ...
-Xlog:help將輸出可能的選項(xiàng)和示例??梢允褂胘cmd命令在運(yùn)行時(shí)修改日志記錄配置。我們將設(shè)置 GC 日志為 info 并將它們重定向到一個(gè)文件 - gc_logs:
jcmd 9615 VM.log output=gc_logs what=gc
(1)不可變集
java.util.Set.of() – 創(chuàng)建給定元素的不可變集合。在 Java 8 中,創(chuàng)建一個(gè)由多個(gè)元素組成的 Set 需要幾行代碼?,F(xiàn)在我們可以簡(jiǎn)單地做到這一點(diǎn):
Set<String> strKeySet = Set.of("key1", "key2", "key3");
(2)可選擇流式傳輸
java.util.Optional.stream()為我們提供了一種在 Optional 元素上使用 Streams 功能的簡(jiǎn)單方法:
List<String> filteredList = listOfOptionals.stream()
.flatMap(Optional::stream)
.collect(Collectors.toList());
Java實(shí)驗(yàn)班
0基礎(chǔ) 0學(xué)費(fèi) 15天面授
Java就業(yè)班
有基礎(chǔ) 直達(dá)就業(yè)
Java夜校直播班
業(yè)余時(shí)間 高薪轉(zhuǎn)行
Java在職加薪班
工作1~3年,加薪神器
Java架構(gòu)師班
工作3~5年,晉升架構(gòu)
提交申請(qǐng)后,顧問老師會(huì)電話與您溝通安排學(xué)習(xí)