国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當(dāng)前位置: 首頁 > news >正文

引擎網(wǎng)站推廣法怎么做google下載app

引擎網(wǎng)站推廣法怎么做,google下載app,做設(shè)計(jì)去哪些網(wǎng)站下載素材,上杭網(wǎng)站建設(shè)工程 | JOSH LONG | 0條評論 Java 22發(fā)布快樂! Java 22 是一個(gè)重大的進(jìn)步,是一個(gè)值得升級版本。有一些重大的最終發(fā)布功能,如 Project Panama及一系列更優(yōu)秀的預(yù)覽功能。我不可能覆蓋它們?nèi)?amp;#xff0c;但我確實(shí)想談?wù)勎易钕矏鄣囊恍?。我們?article class="baidu_pl">

工程 | JOSH LONG | 0條評論

Java 22發(fā)布快樂!

Java 22 是一個(gè)重大的進(jìn)步,是一個(gè)值得升級版本。有一些重大的最終發(fā)布功能,如 Project Panama及一系列更優(yōu)秀的預(yù)覽功能。我不可能覆蓋它們?nèi)?#xff0c;但我確實(shí)想談?wù)勎易钕矏鄣囊恍N覀儗婕暗皆S多功能。如果你想在家里跟著做,代碼在這。

我愛Java 22,當(dāng)然,我也愛 GraalVM,它們都在發(fā)布了新版本!Java 當(dāng)然是我們最喜愛的運(yùn)行時(shí)和語言,而 GraalVM 是一個(gè)高性能的 JDK 發(fā)行版,它支持更多語言并允許提前編譯(它們被稱為 GraalVM native images)。GraalVM 包含了 Java 22 新版的所有好東西,還有一些額外的工具,所以我總是推薦下載那個(gè)版本。我特別感興趣的是 GraalVM native image 的能力。生成的二進(jìn)制文件幾乎可以立即啟動,并且與它們的 JRE 相比,消耗的 RAM 明顯少。GraalVM 不是新事物,但值得記住的是,Spring Boot 有一個(gè)很棒的引擎,支持將你的 Spring Boot 應(yīng)用程序轉(zhuǎn)化為 GraalVM native images。

1 安裝

我正在使用一個(gè)出色的 Java 包管理器 SDKMAN。我還在運(yùn)行帶有 macOS 的 Apple Silicon 芯片。所以,這個(gè)事實(shí)和我喜歡并鼓勵使用 GraalVM 的事實(shí)稍后會有些重要,所以不要忘了。將會有測試!

sdk install java 22-graalce

我還會設(shè)置它為你的默認(rèn)選擇:

sdk default java 22-graalce

在繼續(xù)之前,打開一個(gè)新的 shell,然后通過運(yùn)行 javac --versionjava --version,和 native-image --version 來驗(yàn)證一切是否正常。

如果你是在遙遠(yuǎn)的未來閱讀這篇文章的(我們已經(jīng)有飛行汽車了嗎?)而且有 50-graalce,那么就盡情安裝那個(gè)版本!版本越新越好!

2 你總得從某處開始...

在這一點(diǎn)上,我想要開始構(gòu)建了!所以,我去了互聯(lián)網(wǎng)上第二喜歡的地方,Spring Initializr - start.spring.io - 并生成了一個(gè)新的項(xiàng)目,使用以下規(guī)格:

  • 我選擇了 3.3.0-snapshot 版本的 Spring Boot。3.3 還沒有正式發(fā)行,但應(yīng)該在短短幾個(gè)月內(nèi)就會。與此同時(shí),不斷前進(jìn)!這個(gè)版本對 Java 22 有更好的支持。
  • 我選擇了 Maven 作為構(gòu)建工具。
  • 我添加了 GraalVM Native Support 支持,H2 Database,和 JDBC API 支持。

我在我的 IDE 中打開了項(xiàng)目,像這樣:idea pom.xml?,F(xiàn)在我需要配置一些 Maven 插件以支持 Java 22 和一些我們將在本文中看到的預(yù)覽功能。這是我的完整配置的 pom.xml。它有點(diǎn)密集,所以我會在代碼結(jié)束后來介紹一下。

COPY<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.3.0-SNAPSHOT</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.example</groupId><artifactId>demo</artifactId><version>0.0.1-SNAPSHOT</version><name>demo</name><description>Demo project for Spring Boot</description><properties><java.version>22</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency><dependency><groupId>com.h2database</groupId><artifactId>h2</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.graalvm.sdk</groupId><artifactId>graal-sdk</artifactId><version>23.1.2</version></dependency><dependency><groupId>org.graalvm.nativeimage</groupId><artifactId>svm</artifactId><version>23.1.2</version><scope>provided</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.graalvm.buildtools</groupId><artifactId>native-maven-plugin</artifactId><version>0.10.1</version><configuration><buildArgs><buildArg> --features=com.example.demo.DemoFeature</buildArg><buildArg> --enable-native-access=ALL-UNNAMED </buildArg><buildArg> -H:+ForeignAPISupport</buildArg><buildArg> -H:+UnlockExperimentalVMOptions</buildArg><buildArg> --enable-preview</buildArg></buildArgs></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin</artifactId><configuration><argLine>--enable-preview</argLine></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><enablePreview>true</enablePreview></configuration></plugin><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><compilerArguments> --enable-preview </compilerArguments><jvmArguments> --enable-preview</jvmArguments></configuration></plugin><plugin><groupId>io.spring.javaformat</groupId><artifactId>spring-javaformat-maven-plugin</artifactId><version>0.0.41</version><executions><execution><phase>validate</phase><inherited>true</inherited><goals><goal>validate</goal></goals></execution></executions></plugin></plugins></build><repositories><repository><id>spring-milestones</id><name>Spring Milestones</name><url>https://repo.spring.io/milestone</url><snapshots><enabled>false</enabled></snapshots></repository><repository><id>spring-snapshots</id><name>Spring Snapshots</name><url>https://repo.spring.io/snapshot</url><releases><enabled>false</enabled></releases></pository></repositories><pluginRepositories><pluginRepository><id>spring-milestones</id><name>Spring Milestones</name><url>https://repo.spring.io/milestone</url><snapshots><enabled>false</enabled></snapshots></pluginRepository><pluginRepository><id>spring-snapshots</id><name>Spring Snapshots</name><url>https://repo.spring.io/snapshot</url><releases><enabled>false</enabled></releases></pluginRepository></pluginRepositories>
</project>

我知道,我知道!很多!但實(shí)際上并不是這樣。這個(gè) pom.xml 幾乎和我從 Spring Initializr 獲取的一模一樣。主要改變:

  • 重新定義 maven-surefire-pluginmaven-compiler-plugin 支持預(yù)覽功能。
  • 添加 spring-javaformat-maven-plugin 用來支持格式化我的源代碼。
  • 添加兩個(gè)新依賴項(xiàng):org.graalvm.sdk:graal-sdk:23.1.2org.graalvm.nativeimage:svm:23.1.2,都是專門為后面我們將需要的 GraalVM Feature 實(shí)現(xiàn)創(chuàng)建的
  • native-maven-pluginspring-boot-maven-plugin<configuration> 部分添加了配置節(jié)

非??炀偷搅?#xff0c;Spring Boot 3.3 將會正式發(fā)布并支持 Java 22,所以可能這個(gè)構(gòu)建文件的一半會消失。(真是春天的清理!)

3 編程快速說明

LanguageDemonstrationRunner ,一個(gè)功能性接口,聲明可拋 Throwable。

package com.example.demo;@FunctionalInterface
interface LanguageDemonstrationRunner {void run() throws Throwable;}

我還有一個(gè) ApplicationRunner,反過來,它注入了我所有的功能接口實(shí)現(xiàn),然后調(diào)用它們的 run 方法,捕獲并處理 Throwable

    // ...    @BeanApplicationRunner demo(Map<String, LanguageDemonstrationRunner> demos) {return _ -> demos.forEach((_, demo) -> {try {demo.run();} //catch (Throwable e) {throw new RuntimeException(e);}});}// ...

好的,既然我們已經(jīng)講過了,那就開始吧!

4 再見,JNI!

此版本終于等待了已久的 Project Panama 的發(fā)布。我最期待的三個(gè)特性之一,另外兩個(gè)特性是:

  • 虛擬線程
  • GraalVM native images

它們至少已經(jīng)成為現(xiàn)實(shí)六個(gè)月了。Project Panama 是讓我們能夠利用長期以來被拒之門外的 C 和 C++ 代碼的星系?;叵肫饋?#xff0c;如果它支持 ELF,我想象。例如 Rust 和 Go 程序可以編譯成與 C 兼容的二進(jìn)制文件,所以我想象(但沒有嘗試過)這意味著與這些語言的互操作也足夠容易。在本節(jié)中,當(dāng)我提到“原生代碼”時(shí),我指的是以某種方式編譯的二進(jìn)制文件,它們可以像 C 庫那樣被調(diào)用。

從歷史上看,Java 一直是孤立的。對于 Java 開發(fā)人員來說,重新使用原生 C 和 C++ 代碼并不容易。這是有道理的。原生、特定于操作系統(tǒng)的代碼只會破壞 Java 的“一次編寫,到處運(yùn)行”的承諾。它一直是有點(diǎn)禁忌的。但我不明白為什么會這樣。公平地說,盡管缺乏易用的原生代碼互操作功能,我們也做得不錯。幾乎任何你想要做的事情,可能都有一個(gè)純 Java 解決方案存在,它可以在 Java 運(yùn)行的任何地方運(yùn)行。它運(yùn)行得很好,直到它不再運(yùn)行。Java 在這里錯過了關(guān)鍵的機(jī)會。想象一下:

  • 如果 Kubernetes 是用 Java 構(gòu)建的?
  • 如果當(dāng)前的 AI 革命是由 Java 驅(qū)動的?

這兩個(gè)概念會不可思議,當(dāng) Numpy、Scipy 和 Kubernetes 最初創(chuàng)建時(shí),但是今天?今天,他們發(fā)布了 Panama 項(xiàng)目。

Panama 項(xiàng)目引入了一種容易連接原生代碼的方法。支持兩個(gè)級別。你可以以相當(dāng)?shù)图壍姆绞讲倏v內(nèi)存,并將數(shù)據(jù)在原生代碼中來回傳遞。我說“來回”,但我可能應(yīng)該說“向下和向上”到原生代碼。Panama 項(xiàng)目支持“向下調(diào)用”,即從 Java 調(diào)用原生代碼,以及“向上調(diào)用”,即從原生代碼調(diào)用 Java。你可以調(diào)用函數(shù)、分配和釋放內(nèi)存、讀取和更新 struct 中的字段等等。

讓我們來看一個(gè)簡單的例子。代碼使用新的 java.lang.foreign.* API 查找一個(gè)叫做 printf 的符號(基本上就是 System.out.print()),分配內(nèi)存(有點(diǎn)像 malloc)緩沖區(qū),然后將該緩沖區(qū)傳遞給 printf 函數(shù)。

package com.example.demo;import org.springframework.stereotype.Component;import java.lang.foreign.Arena;
import java.lang.foreign.FunctionDescriptor;
import java.lang.foreign.Linker;
import java.lang.foreign.SymbolLookup;
import java.util.Objects;import static java.lang.foreign.ValueLayout.ADDRESS;
import static java.lang.foreign.ValueLayout.JAVA_INT;@Component
class ManualFfi implements LanguageDemonstrationRunner {// 這是包私有的,因?yàn)槲覀兩院髸枰黶tatic final FunctionDescriptor PRINTF_FUNCTION_DESCRIPTOR =FunctionDescriptor.of(JAVA_INT, ADDRESS);private final SymbolLookup symbolLookup;// SymbolLookup 是 Panama API,但我有一個(gè)我正在注入的實(shí)現(xiàn)ManualFfi(SymbolLookup symbolLookup) {this.symbolLookup = symbolLookup;}@Overridepublic void run() throws Throwable {var symbolName = "printf";var nativeLinker = Linker.nativeLinker();var methodHandle = this.symbolLookup.find(symbolName).map(symbolSegment -> nativeLinker.downcallHandle(symbolSegment, PRINTF_FUNCTION_DESCRIPTOR)).orElse(null);try (var arena = Arena.ofConfined()) {var cString = arena.allocateFrom("hello, Panama!");Objects.requireNonNull(methodHandle).invoke(cString);}}}

這是我提出的 SymbolLookup 的定義。它是一種復(fù)合體,嘗試一個(gè) SymbolLookup,如果第一個(gè)失敗,則嘗試另一個(gè)。

@Bean
SymbolLookup symbolLookup() {var loaderLookup = SymbolLookup.loaderLookup();var stdlibLookup = Linker.nativeLinker().defaultLookup();return name -> loaderLookup.find(name).or(() -> stdlibLookup.find(name));
}

運(yùn)行這個(gè),你會看到它打印出 hello, Panama!.

您可能想知道為什么我沒有選擇更有趣的例子。事實(shí)證明,在所有os中你既能理所當(dāng)然地享有,在計(jì)算機(jī)上也能感知到自己做了些什么的東西幾乎沒有。IO 似乎是我能想到的所有東西,而且控制臺 IO 更容易理解。

但 GraalVM 原生鏡像咋樣呢?它并不支持你可能想做的每件事。至少目前,它不在蘋果芯片運(yùn)行,只在 x86 芯片。我開發(fā)了這個(gè)例子,并設(shè)置了 GitHub 操作在 x86 Linux 環(huán)境中查看結(jié)果。對于我們這些不使用英特爾芯片的 Mac 開發(fā)者來說,這有點(diǎn)遺憾,但我們大多數(shù)人不是將產(chǎn)品部署到蘋果設(shè)備上,我們是部署到 Linux 和 x86 上,所以這不是一個(gè)破壞協(xié)議的事情。

還有一些其他限制。如GraalVM 原生映像僅支持我們復(fù)合中的第一個(gè) SymbolLookup, loaderLookup。如果那個(gè)不起作用,那么它們都將不起作用。

GraalVM 想要知道你在運(yùn)行時(shí)會做的一些動態(tài)事情,包括外部函數(shù)調(diào)用。你需要提前告訴它。對于其他需要此類信息的大多數(shù)事情,如反射、序列化、資源加載等,你需要編寫 .json 配置文件(或讓 Spring 的 AOT 引擎為你編寫)。這個(gè)特性是如此新,以至于你必須走下幾個(gè)抽象層次并編寫一個(gè) GraalVM Feature 類。Feature 有回調(diào)方法,在 GraalVM 的本地編譯生命周期中被調(diào)用。你將告訴 GraalVM 我們最終會在運(yùn)行時(shí)調(diào)用的原生函數(shù)的簽名,即形態(tài)。這是 Feature。只有一行價(jià)值。

package com.example.demo;import org.graalvm.nativeimage.hosted.Feature;
import org.graalvm.nativeimage.hosted.RuntimeForeignAccess;import static com.example.demo.ManualFfi.PRINTF_FUNCTION_DESCRIPTOR;public class DemoFeature implements Feature {@Overridepublic void duringSetup(DuringSetupAccess access) {// 這是唯一重要的一行。注意:我們正在分享// 我們稍早從 ManualFfi bean 中的 PRINTF_FUNCTION_DESCRIPTOR。RuntimeForeignAccess.registerForDowncall(PRINTF_FUNCTION_DESCRIPTOR);}}

然后我們需要連接所有的特性,通過將 --features 屬性傳遞給 GraalVM 原生圖像 Maven 插件配置來告知 GraalVM。我們還需要解鎖外部 API 支持和解鎖實(shí)驗(yàn)性事物。(我不知道為什么在 GraalVM 原生鏡像中這是實(shí)驗(yàn)性的,而在 Java 22 本身中它不再是實(shí)驗(yàn)性的)。還需要告訴 GraalVM 允許所有未命名類型的原生訪問。所以,總的來說,這是最終的 Maven 插件配置。

<plugin><groupId>org.graalvm.buildtools</groupId><artifactId>native-maven-plugin</artifactId><version>0.10.1</version><configuration><buildArgs><buildArg>--features=com.example.demo.DemoFeature</buildArg><buildArg>--enable-native-access=ALL-UNNAMED</buildArg><buildArg>-H:+ForeignAPISupport</buildArg><buildArg>-H:+UnlockExperimentalVMOptions</buildArg><buildArg>--enable-preview</buildArg></buildArgs></configuration>
</plugin>

這是一個(gè)了不起的結(jié)果。我將這個(gè)示例中的代碼編譯成一個(gè)在 GitHub Actions 運(yùn)行中的 GraalVM 原生圖像然后執(zhí)行它。應(yīng)用程式,我提醒您 - 具有 Spring JDBC 支持、完整和嵌入式 SQL 99 兼容的 Java 數(shù)據(jù)庫叫做 H2,以及類路徑上的所有內(nèi)容 - 在 0.031 秒(31 毫秒,或 31 千分之一秒)內(nèi)執(zhí)行,占用數(shù)十兆字節(jié)的 RAM,并從 GraalVM 原生鏡像調(diào)用原生 C 代碼!

我真的很高興,大家。我已經(jīng)等這一天很久了。

但這確實(shí)感覺有點(diǎn)低級。歸根到底,你在使用一個(gè) Java API 來以編程方式創(chuàng)建和維護(hù)原生代碼中的結(jié)構(gòu)。這有點(diǎn)像使用 JDBC 中的 SQL。JDBC 允許你在 Java 中操縱 SQL 數(shù)據(jù)庫記錄,但你不是在 Java 中編寫 SQL 并在 Java 中編譯它并在 SQL 中執(zhí)行它。存在一個(gè)抽象增量;你將字符串發(fā)送到 SQL 引擎,然后以 ResultSet 對象的形式獲取回來的記錄。Panama 中的低級 API 也是如此。它起作用,但你沒有調(diào)用原生代碼,你正在查找符號和操縱內(nèi)存。

所以,他們發(fā)布了一個(gè)與之分離但相關(guān)的工具叫做 jextract。你可以指向一個(gè) C 頭文件,如 stdio.hprintf 函數(shù)定義在其中,它會生成模仿底層 C 代碼調(diào)用簽名的 Java 代碼。我沒有在這個(gè)示例中使用它,因?yàn)樯傻?Java 代碼最終與底層平臺綁定。我指它去 stdio.h 并獲得了很多 macOS 特定的定義。我可以隱藏所有這些在運(yùn)行時(shí)檢查操作系統(tǒng)的后面,然后動態(tài)加載特定的實(shí)現(xiàn),但是,嗯,這篇博客已經(jīng)太長了。如果你想看怎么運(yùn)行 jextract,這是我用的可以在 macOS 和 Linux 上工作的 bash 腳本。你的里程可能會有所不同。

#!/usr/bin/env bash
LINUX=https://download.java.net/java/early_access/jextract/22/3/openjdk-22-jextract+3-13_linux-x64_bin.tar.gz
MACOS=https://download.java.net/java/early_access/jextract/22/3/openjdk-22-jextract+3-13_macos-x64_bin.tar.gzOS=$(uname)DL=""
STDIO=""if [ "$OS" = "Darwin" ]; thenDL="$MACOS"STDIO=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/stdio.h
elif [ "$OS" = "Linux" ]; thenDL=$LINUXSTDIO=/usr/include/stdio.h
elseecho "Are you running on Windows? This might work inside the Windows Subsystem for Linux, but I haven't tried it yet.."
fiLOCAL_TGZ=tmp/jextract.tgz
REMOTE_TGZ=$DL
JEXTRACT_HOME=jextract-22mkdir -p "$(dirname  $LOCAL_TGZ )"
wget -O $LOCAL_TGZ $REMOTE_TGZ
tar -zxf "$LOCAL_TGZ" -C .
export PATH=$PATH:$JEXTRACT_HOME/binjextract  --output src/main/java  -t com.example.stdio $STDIO

想想看,我們擁有簡單的外部函數(shù)互操作性、提供驚人擴(kuò)展性的虛擬線程,以及靜態(tài)鏈接的、快如閃電、內(nèi)存高效、自足的 GraalVM 原生圖像二進(jìn)制文件。再次告訴我,為何你要開始一個(gè)新的 Go 項(xiàng)目?:-)

5 勇敢的新世界

Java 22 是一個(gè)驚人的新版本。它帶來了一系列巨大的功能和提升生活品質(zhì)的改進(jìn)。記住,不可能總是這樣美好!沒有人能每六個(gè)月就一貫地推出改變游戲規(guī)則的新功能。這是不可能的。所以,我們不妨心存感激,盡情享受目前吧,好嗎? :) 在我看來,上一個(gè)版本 Java 21,或許是我見過的自 Java 5 以來最重要的一次發(fā)布,甚至可能是最早。這可能是最大的一次!

那里有許多特性值得你關(guān)注,包括:

  • 數(shù)據(jù)導(dǎo)向編程
  • 虛擬線程

六月前為支持那次發(fā)布所做的博客中,覆蓋這些及更多內(nèi)容,Hello, Java 21。

6 虛擬線程、結(jié)構(gòu)化并發(fā)和作用域值

虛擬線程是真正重要的部分。閱讀我剛才鏈接給你的博客,往下翻。 (不要像 the Primeagen 那樣,他讀了文章但在還沒讀到最佳部分 - 虛擬線程之前就走神了!我的朋友……為什么??)

如果你正在運(yùn)行 I/O 綁定的服務(wù),虛擬線程是提高你的云基礎(chǔ)設(shè)施花費(fèi)、硬件等的一個(gè)方法。它們使得你可以將現(xiàn)有的針對 java.io 中的阻塞 I/O API 編寫的代碼轉(zhuǎn)換為虛擬線程,并處理更好的規(guī)?;?。通常的效果是,你的系統(tǒng)不再不斷地等待線程的可用性,從而平均響應(yīng)時(shí)間下降,更好的是,你會發(fā)現(xiàn)系統(tǒng)能夠同時(shí)處理更多的請求!我無法強(qiáng)調(diào)它的重要性。虛擬線程是棒極了!如果你在使用 Spring Boot 3.2,你只需要指定 spring.threads.virtual.enabled=true 即可享受它們!

虛擬線程是旨在使 Java 成為我們都知道它應(yīng)該得到的精簡、高效的規(guī)?;瘷C(jī)器的一系列新功能的一部分,而且它正在起作用!虛擬線程是三個(gè)旨在協(xié)同工作的功能中的唯一一個(gè)已經(jīng)在發(fā)布形式中交付的功能。

結(jié)構(gòu)化并發(fā)和作用域值都還沒有落地。結(jié)構(gòu)化并發(fā)為構(gòu)建并發(fā)代碼提供了一個(gè)更優(yōu)雅的編程模型,而作用域值則提供了一個(gè)效率更高、更通用的 ThreadLocal<T> 替代方案,特別適用于虛擬線程的背景下,其中你現(xiàn)在可以實(shí)際擁有數(shù)百萬個(gè)線程。想象一下對于每一個(gè)這樣的線程都有重復(fù)的數(shù)據(jù)!

這些功能在 Java 22 中處于預(yù)覽階段。我不知道它們現(xiàn)在是否值得展示。在我心中,虛擬線程是魔法的一部分,它們之所以如此神奇,正是因?yàn)槟阏娴牟恍枰私馑鼈?#xff01;只設(shè)置那一個(gè)屬性,你就可以啟動了。

虛擬線程為你提供了類似 Python、Rust、C#、TypeScript、JavaScript 的 async/await 或 Kotlin 中的 suspend 之類的驚人規(guī)模,而無需使用那些語言功能所需的固有冗長代碼和繁瑣工作。這是少數(shù)幾次,除了可能是 Go 的實(shí)現(xiàn),Java 在結(jié)果上是直接更勝一籌的時(shí)候。Go 的實(shí)現(xiàn)是理想的,但那只是因?yàn)樗麄冊?1.0 版本中就內(nèi)置了這一點(diǎn)。事實(shí)上,Java 的實(shí)現(xiàn)更為杰出,精確地說是因?yàn)樗c較老的平臺線程模型共存。

7 隱式聲明的類和實(shí)例主方法

這個(gè)預(yù)覽功能是巨大的生活質(zhì)量提升,盡管結(jié)果代碼更小,而我非常歡迎它。不幸的是,它目前還與 Spring Boot 不兼容。基本概念是,總有一天你將能夠只有一個(gè)頂層 main 方法,而不需要今天 Java 中的所有儀式。作為應(yīng)用程序的入口點(diǎn),這不是很好嗎?沒有 class 定義,沒有 public static void,沒有不必要的 String[] 參數(shù)。

void main() {System.out.println("Hello, world!");
}

8 超類之前的語句

這是一個(gè)不錯的生活質(zhì)量功能?;旧?#xff0c;Java 不允許你在子類中調(diào)用 super 構(gòu)造函數(shù)之前訪問 this。其目的是為了避免與無效狀態(tài)相關(guān)的一類錯誤。但這有點(diǎn)過于嚴(yán)厲,并迫使開發(fā)者在想要在調(diào)用 super 方法之前進(jìn)行任何非平凡計(jì)算時(shí),不得不轉(zhuǎn)而使用 private static 輔助方法。這是有時(shí)所需的體操動作的一個(gè)例子。我從 the JEP 頁面偷來了這個(gè)例子:

class Sub extends Super {Sub(Certificate certificate) {super(prepareByteArray(certificate));}// 輔助方法private static byte[] prepareByteArray(Certificate certificate) {var publicKey = certificate.getPublicKey();if (publicKey == null)throw new IllegalArgumentException("null certificate");return switch (publicKey) {case RSAKey rsaKey -> ///...case DSAPublicKey dsaKey -> ...//...default -> //...};}}

你可以看到問題。這個(gè)新的 JEP,目前還是預(yù)覽功能,將允許你將該方法直接內(nèi)聯(lián)在構(gòu)造函數(shù)本身,增強(qiáng)可讀性并消除代碼冗余。

9 未命名的變量和模式

未命名的變量和模式是另一個(gè)提升生活質(zhì)量的功能。然而,它已經(jīng)交付了。

當(dāng)你在創(chuàng)建線程,或者使用 Java 8 的流和收集器時(shí),你將創(chuàng)建很多 lambda。實(shí)際上,在 Spring 中有很多情況下你會使用 lambdas。只需考慮所有的 *Template 對象,及其以回調(diào)為中心的方法。 JdbcClientRowMapper<T> 也跳入腦海!

有趣的事實(shí):Lambda 首次在 2014 年的 Java 8 版本中介紹。 (是的,已經(jīng)過去了一個(gè)十年!那時(shí)人們在做冰桶挑戰(zhàn),世界癡迷于自拍棒、FrozenFlappy Bird。),但它們的驚人品質(zhì)是幾乎前 20 年的 Java 代碼在一夜之間如果方法期望單個(gè)方法接口實(shí)現(xiàn)就可以參與 lambdas。

Lambdas 是驚人的。它們在 Java 語言中引入了一個(gè)新的重用單元。最棒的部分是它們被設(shè)計(jì)為以某種方式嫁接到運(yùn)行時(shí)的現(xiàn)有規(guī)則上,包括自動將所謂的功能接口或 SAMs(單抽象方法)接口適應(yīng)到 lambdas。我唯一的抱怨是,屬于包含作用域的 lambda 中引用的東西必須設(shè)置為 final。這個(gè)問題已經(jīng)修復(fù)?,F(xiàn)在必須拼出每個(gè) lambda 參數(shù),即使我根本沒打算使用它,現(xiàn)在,有了 Java 22,那也得到修復(fù)了!這里是一個(gè)冗長的例子,僅為了展示兩處 _ 字符的使用。因?yàn)槲铱梢浴?/p>

package com.example.demo;import org.springframework.jdbc.core.simple.JdbcClient;
import org.springframework.stereotype.Component;import javax.sql.DataSource;@Component
class AnonymousLambdaParameters implements LanguageDemonstrationRunner {private final JdbcClient db;AnonymousLambdaParameters(DataSource db) {this.db = JdbcClient.create(db);}record Customer(Integer id, String name) {}@Overridepublic void run() throws Throwable {var allCustomers = this.db.sql("select * from customer ")// 這里! .query((rs, _) -> new Customer(rs.getInt("id"), rs.getString("name"))).list();System.out.println("all: " + allCustomers);}}

該類使用 Spring 的 JdbcClient 查詢底層數(shù)據(jù)庫。它一頁一頁地翻閱結(jié)果,然后涉及我們的 lambda,它符合 RowMapper<Customer> 類型,以幫助我們將結(jié)果適應(yīng)到與我的領(lǐng)域模型一致的記錄。 RowMapper<T> 接口,我們的 lambda 符合它,有一個(gè)方法 T mapRow(ResultSet rs, int rowNum) throws SQLException,期望兩個(gè)參數(shù):我將需要的 ResultSet,以及我?guī)缀醪恍枰?rowNum?,F(xiàn)在,多虧 Java 22,我不需要指定它。就像在 Kotlin 或 TypeScript 中一樣,只需插入 _ 即可。不錯!

10 聚集者

Gatherers 是另一個(gè)在預(yù)覽中也很好的功能。 Viktor Klang,他在 Akka 上的了不起工作以及他在 Lightbend 期間對 Scala futures 的貢獻(xiàn)。如今,他是 Oracle 的一名 Java 語言架構(gòu)師,他一直在研究的就是新的 Gatherer API。順便說一下,Stream API 也是在 Java 8 中引入的,這 - 順便說一下 - 給了 Java 開發(fā)者一個(gè)機(jī)會,與 lambdas 一起,大大簡化和現(xiàn)代化他們現(xiàn)有的代碼,并向更多函數(shù)式編程方向發(fā)展。

它構(gòu)建了一個(gè)在值的流上進(jìn)行一系列轉(zhuǎn)換的模型。然而,這個(gè)抽象模型并不盡完美。Streams API 提供了大量便利的方法,這些方法能夠滿足 99% 的使用場景,但當(dāng)你遇到找不到合適方法的情況時(shí),通常會感到挫敗,因?yàn)橹安]有一種簡易的方式可以直接擴(kuò)展新的操作。在過去十年間,關(guān)于為 Streams API 引入新操作的提案數(shù)不勝數(shù),甚至在最初的 lambda 表達(dá)式提案中,也有討論和妥協(xié),目的是讓編程模型有足夠的靈活性來支持新操作的加入?,F(xiàn)在,這一目標(biāo)作為一個(gè)預(yù)覽性質(zhì)的功能終于實(shí)現(xiàn)了。Gatherers 提供了一個(gè)稍微更底層的抽象層次,使你能夠在不需要將 Stream 具體化為 Collection 的情況下,在 Streams 上引入多種新操作。以下是一個(gè)我毫不掩飾地直接從 Viktor 和他的團(tuán)隊(duì)那里取得的示例。

package com.example.demo;import org.springframework.stereotype.Component;import java.util.Locale;
import java.util.function.BiFunction;
import java.util.function.Supplier;
import java.util.stream.Gatherer;
import java.util.stream.Stream;@Component
class Gatherers implements LanguageDemonstrationRunner {private static <T, R> Gatherer<T, ?, R> scan(Supplier<R> initial,BiFunction<? super R, ? super T, ? extends R> scanner) {class State {R current = initial.get();}return Gatherer.<T, State, R>ofSequential(State::new,Gatherer.Integrator.ofGreedy((state, element, downstream) -> {state.current = scanner.apply(state.current, element);return downstream.push(state.current);}));}@Overridepublic void run() {var listOfNumberStrings = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9).gather(scan(() -> "", (string, number) -> string + number).andThen(java.util.stream.Gatherers.mapConcurrent(10, s -> s.toUpperCase(Locale.ROOT)))).toList();System.out.println(listOfNumberStrings);}}

該段代碼的重點(diǎn)在于,這里描述了一個(gè)名為 scan 的方法,它返回一個(gè) Gatherer<T,?,R> 類型的實(shí)現(xiàn)。每個(gè) Gatherer<T,O,R> 對象都需要一個(gè)初始化函數(shù)和一個(gè)整合函數(shù)。雖然這種實(shí)現(xiàn)自帶默認(rèn)的合并函數(shù)和完成函數(shù),但你也可以自行覆蓋它們。它通過讀取所有的數(shù)字條目,并為每一個(gè)條目逐步構(gòu)造一個(gè)字符串,字符串隨著數(shù)字的增加不斷累積。結(jié)果就像這樣:先是 1,然后是 12,接著是 123,直到 1234 等等。 上述例子還展示了 gatherers 是可以組合使用的。在這里,我們實(shí)際上操作了兩個(gè) Gatherer 對象:一個(gè)用于執(zhí)行掃描過程,另一個(gè)則把每個(gè)元素轉(zhuǎn)成大寫,并且這一轉(zhuǎn)換是并發(fā)進(jìn)行的。 如果您還沒能完全理解,沒關(guān)系,對于大多數(shù)人而言,這部分內(nèi)容可能會有些深奧。大多數(shù)人可能無需自己編寫 Gatherers。但是,如果你想挑戰(zhàn)一下,也是可以試試的。我的朋友 Gunnar Morling 就在前幾天完成了這樣的工作。Gatherers 方法的巧妙之處在于,它使社區(qū)能夠根據(jù)自己的需求去設(shè)計(jì)解決方案。我很好奇這對于 Eclipse Collections、Apache Commons Collections 或者 Guava 這樣的著名項(xiàng)目會帶來什么影響?它們是否會推出 Gatherers?還有其他什么項(xiàng)目會加入這一趨勢?我期待看到很多實(shí)用的 gatherers 能夠聚集到同一個(gè)地方。

11 Class Parsing API

又一個(gè)令人期待的預(yù)覽性特性,這是 JDK 新增的部分,非常適合框架和基礎(chǔ)架構(gòu)開發(fā)人員。它可以解答例如如何構(gòu)建 .class 文件和如何讀取 .class 文件的問題。目前市場上有很多好用但不兼容,總是稍微有點(diǎn)落后的工具,比如 ASM(這個(gè)領(lǐng)域里的重量級解決方案),ByteBuddy,CGLIB 等。JDK 本身在其代碼庫中就包含了三種此類解決方案!這類庫在整個(gè)行業(yè)中隨處可見,并且對于像 Spring 這樣的框架的開發(fā)來說至關(guān)重要,Spring 動態(tài)地在運(yùn)行時(shí)創(chuàng)建類來支持業(yè)務(wù)邏輯。你可以將它看作是一個(gè)反射 API,但它作用于 .class 文件——硬盤上實(shí)際的字節(jié)碼,而不是加載進(jìn) JVM 的對象。 這是一個(gè)簡單的例子,展示了如何把一個(gè) .class 文件加載進(jìn)一個(gè) byte[] 數(shù)組,并對其進(jìn)行分析。

package com.example.demo;import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;
import org.springframework.context.annotation.ImportRuntimeHints;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Component;import java.lang.classfile.ClassFile;
import java.lang.classfile.FieldModel;
import java.lang.classfile.MethodModel;@Component
@ImportRuntimeHints(ClassParsing.Hints.class)
class ClassParsing implements LanguageDemonstrationRunner {static class Hints implements RuntimeHintsRegistrar {@Overridepublic void registerHints(RuntimeHints hints, ClassLoader classLoader) {hints.resources().registerResource(DEFAULT_CUSTOMER_SERVICE_CLASS);}}private final byte[] classFileBytes;private static final Resource DEFAULT_CUSTOMER_SERVICE_CLASS = new ClassPathResource("/simpleclassfile/DefaultCustomerService.class");ClassParsing() throws Exception {this.classFileBytes = DEFAULT_CUSTOMER_SERVICE_CLASS.getContentAsByteArray();}@Overridepublic void run() {// this is the important logicvar classModel = ClassFile.of().parse(this.classFileBytes);for (var classElement : classModel) {switch (classElement) {case MethodModel mm -> System.out.printf("Method %s%n", mm.methodName().stringValue());case FieldModel fm -> System.out.printf("Field %s%n", fm.fieldName().stringValue());default -> {// ... }}}}}

這個(gè)例子稍微復(fù)雜一些,因?yàn)樗婕暗搅诉\(yùn)行時(shí)讀取資源。為了應(yīng)對這個(gè)過程,我實(shí)現(xiàn)了一個(gè)名為 Spring AOT RuntimeHintsRegistrar 的組件,它能生成一個(gè) .json 文件。這個(gè) JSON 文件記錄著我正在讀取的資源信息,比如具體來說就是 DefaultCustomerService.class 文件的數(shù)據(jù)。不過,這些都是幕后的技術(shù)細(xì)節(jié),主要是為了在 GraalVM 上進(jìn)行本地鏡像編譯的時(shí)候使用。 而代碼底部的部分則頗有意思,我們對 ClassElement 實(shí)例進(jìn)行了枚舉,并通過模式匹配的方法一一提取了各個(gè)要素。這真是太棒了!

12 String Templates

又一項(xiàng)預(yù)覽特性的加入,String templates 為 Java 帶來了字符串插值功能!Java 中的多行字符串(String)已經(jīng)使用了一段時(shí)間。這個(gè)新功能允許開發(fā)者將編譯后字符串中可見的變量直接嵌入到字符串值里面。最精彩的部分?從理論上講,這個(gè)機(jī)制還可以自定義!不滿意現(xiàn)有的語法?你完全可以創(chuàng)造一個(gè)屬于你自己的版本。

package com.example.demo;import org.springframework.stereotype.Component;@Component
class StringTemplates implements LanguageDemonstrationRunner {@Overridepublic void run() throws Throwable {var name = "josh";System.out.println(STR.""" name: \{name.toUpperCase()}""");}}

13 總結(jié)

作為一名 Java 和 Spring 開發(fā)者,現(xiàn)在是一個(gè)前所未有的好時(shí)機(jī)!我一直強(qiáng)調(diào)這一點(diǎn)。我們仿佛獲得了一個(gè)嶄新的語言和運(yùn)行時(shí)環(huán)境,這一進(jìn)步 - 奇妙地 - 保持了對歷史版本的兼容。這是我目睹 Java 社區(qū)所開展的最具雄心壯志的軟件項(xiàng)目之一,我們很幸運(yùn)能夠見證其成果的誕生。從現(xiàn)在起,我打算將 Java 22 和支持 Java 22 的 GraalVM 用于我的所有開發(fā)工作,我希望您也能跟我一起 關(guān)注我,緊跟本系列專欄文章,咱們下篇再續(xù)!

作者簡介:魔都技術(shù)專家兼架構(gòu),多家大廠后端一線研發(fā)經(jīng)驗(yàn),各大技術(shù)社區(qū)頭部專家博主。具有豐富的引領(lǐng)團(tuán)隊(duì)經(jīng)驗(yàn),深厚業(yè)務(wù)架構(gòu)和解決方案的積累。

負(fù)責(zé):

  • 中央/分銷預(yù)訂系統(tǒng)性能優(yōu)化

  • 活動&優(yōu)惠券等營銷中臺建設(shè)

  • 交易平臺及數(shù)據(jù)中臺等架構(gòu)和開發(fā)設(shè)計(jì)

  • 車聯(lián)網(wǎng)核心平臺-物聯(lián)網(wǎng)連接平臺、大數(shù)據(jù)平臺架構(gòu)設(shè)計(jì)及優(yōu)化

    目前主攻降低軟件復(fù)雜性設(shè)計(jì)、構(gòu)建高可用系統(tǒng)方向。

參考:

  • 編程嚴(yán)選網(wǎng)

本文由博客一文多發(fā)平臺 OpenWrite 發(fā)布!

http://m.aloenet.com.cn/news/44633.html

相關(guān)文章:

  • 網(wǎng)站建設(shè)常規(guī)自適應(yīng)信息流廣告優(yōu)化師
  • 網(wǎng)站建設(shè)中的html頁面seo網(wǎng)站優(yōu)化培訓(xùn)
  • 2018年網(wǎng)站建設(shè)做搜索引擎推廣多少錢
  • 網(wǎng)站建站客戶需求表單鄭州網(wǎng)站制作選擇樂云seo
  • 做網(wǎng)站最主要是什么招聘seo專員
  • 建設(shè)銀行澳洲招聘網(wǎng)站最新足球消息
  • 禪城網(wǎng)站建設(shè)報(bào)價(jià)it培訓(xùn)課程
  • wordpress文件的完整url地址seo是什么意思啊
  • 響應(yīng)式網(wǎng)站的制作網(wǎng)站制作百度大數(shù)據(jù)查詢平臺
  • 貴陽網(wǎng)站推廣網(wǎng)絡(luò)營銷策劃推廣方案
  • cad培訓(xùn)班一般學(xué)費(fèi)多少深圳網(wǎng)站設(shè)計(jì)專家樂云seo
  • c語言除了做網(wǎng)站還能干什么廣州疫情升級
  • 網(wǎng)站建設(shè)公司六安網(wǎng)站seo方案
  • 龍巖網(wǎng)站建設(shè)全包sem和seo是什么職業(yè)
  • 中企動力做過的網(wǎng)站女教師遭網(wǎng)課入侵視頻
  • wordpress獲取當(dāng)前目錄父目錄id吉林seo管理平臺
  • 縣文化館網(wǎng)站建設(shè)方案市場調(diào)研報(bào)告1000字
  • 哪些網(wǎng)站做ip向小說神秘網(wǎng)站
  • 央視新聞seo的五個(gè)步驟
  • 尋找徐州網(wǎng)站開發(fā)企業(yè)網(wǎng)絡(luò)營銷青島
  • 深圳廣告公司前十強(qiáng)seo簡單速排名軟件
  • 單頁網(wǎng)站在線制作公司搜索seo
  • 做網(wǎng)站上哪買空間鄭州seo顧問外包公司
  • 書畫網(wǎng)站模板下載跨境電商seo什么意思
  • 網(wǎng)絡(luò)營銷的方法包括哪些重慶seo是什么
  • wordpress 子主題路由seo沒什么作用了
  • 素材網(wǎng)站源碼成品視頻直播軟件推薦哪個(gè)好一點(diǎn)
  • 如何仿造一個(gè)網(wǎng)站做廣州網(wǎng)絡(luò)廣告推廣公司
  • 企業(yè)網(wǎng)站 手機(jī)網(wǎng)站 app 微網(wǎng)站廣州網(wǎng)站建設(shè)系統(tǒng)
  • wordpress is_mobile上海關(guān)鍵詞排名優(yōu)化公司