Android Studio中的各種Java版本區別

Android Studio中的各種Java版本

創建一個項目,app模塊的build.gradle.kts默認配置如下:

plugins {alias(libs.plugins.android.application)alias(libs.plugins.kotlin.android)
}android {namespace = "cn.android666.javaversiontest"compileSdk = 35defaultConfig {applicationId = "cn.android666.javaversiontest"minSdk = 21targetSdk = 35versionCode = 1versionName = "1.0"testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"}buildTypes {release {isMinifyEnabled = falseproguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")}}compileOptions {sourceCompatibility = JavaVersion.VERSION_11targetCompatibility = JavaVersion.VERSION_11}kotlinOptions {jvmTarget = "11"}
}dependencies {implementation(libs.androidx.core.ktx)implementation(libs.androidx.appcompat)implementation(libs.material)implementation(libs.androidx.activity)implementation(libs.androidx.constraintlayout)testImplementation(libs.junit)androidTestImplementation(libs.androidx.junit)androidTestImplementation(libs.androidx.espresso.core)
}

這里有關Java版本設置的地方有兩個:

compileOptions {sourceCompatibility = JavaVersion.VERSION_11targetCompatibility = JavaVersion.VERSION_11
}
kotlinOptions {jvmTarget = "11"
}

在設置中還有一個Gradle JDK可以設置和Java版本相關的,如下:
在這里插入圖片描述

各種Java版本功能如下:

  • Gradle JDK:用于運行 Gradle 的JDK(Gradle 是 Java 編寫的工具,所以需要用JDK來運行)

    • 影響 Gradle 守護進程(Daemon)的啟動和執行效率。
    • 從 Gradle 7.0 開始要求最低 ??JDK 11??(AGP 8.0+ 強制要求 JDK 17)。
    • 與項目代碼的編譯版本無關,僅影響構建過程本身。
  • sourceCompatibility:指定 Java ??源代碼??的語言版本(語法兼容性)

    • 限制代碼中使用的語法特性(例如:Java 11 支持 var,但若設為 VERSION_1_8 則不允許使用。注:只限制語法特性,不限制API,比如sourceCompatibility設置為1.7,然后使用Java 8的時間API這是可以的,只要minSdk為26+就行,因為從26+的系統就開始支持Java8的時間API)。
    • 對應 javac -source 參數。
  • targetCompatibility:指定生成的 ??字節碼(.class 文件)?? 的目標 JVM 版本

    • 確保字節碼能在指定版本或更高版本的 JVM 上運行(例如設為 VERSION_11 時,字節碼可運行在 JDK 11+ 環境)。
    • 對應 javac -target 參數。
    • 必須滿足??:targetCompatibility ≥ sourceCompatibility
  • jvmTarget:指定 ??Kotlin 代碼?? 編譯后的字節碼目標版本。

    • 控制 Kotlin 編譯器生成的字節碼版本(類似 Java 的 targetCompatibility,但僅作用于 Kotlin 代碼)。

Gradle JDK 需獨立滿足 AGP 要求:

APG版本最低 Gradle JDK最低Gradle
8.0+JDK 17Gradle 8.0
7.4JDK 11Gradle 7.5

總結

  • Gradle JDK??:構建工具的“發動機”,需獨立配置且版本受 AGP 限制 ?。

  • ??source/targetCompatibility??:控制 Java 代碼的語法和字節碼兼容性 🧩。

  • jvmTarget??:專為 Kotlin 代碼設置字節碼版本 🔧。

驗證編譯后的class的java版本

我的配置為:

compileOptions {sourceCompatibility = JavaVersion.VERSION_11targetCompatibility = JavaVersion.VERSION_11
}
kotlinOptions {jvmTarget = "11"
}

targetCompatibilityjvmTarget都設置為java 11,也就是說編譯的java文件和kotlin文件都會被編譯為java 11的字節碼。且高版本的JDK編譯器可以指定生成低版本字節碼,比如使用JDK21編譯生成JDK11的字節碼:javac -release 11 YourClass.java,Kotlin也有類似的編譯,比如:kotlinc Hello.kt -jvm-target 11 -d output.jar

我的Android項目中同時有Kotlin文件和Java文件:MainActivity.ktUtil.java,運行項目到手機,然后代碼會被編譯。

  • java編譯結果保存路徑:

    app\build\intermediates\javac\debug\compileDebugJavaWithJavac\classes
    
  • kotlin編譯結果保存路徑:

    app\build\tmp\kotlin-classes\debug
    

Android Studio 支持直接反編譯class文件的,雙擊編譯后的文件,截圖如下:

在這里插入圖片描述
在這里插入圖片描述
從反編譯文件可以看到信息:Decompiled .class file, bytecode version: 55.0(Java 11),中文翻譯為:反編譯的.class文件,字節碼版本:55.0(Java 11),字節碼版本為55.0,對應的就是Java 11版本。

驗證各種Java版本

一、純Java項目

1. 當前配置

  • Android Studio版本:Android Studio Meerkat Feature Drop | 2024.3.2 Patch 1

  • Gradle JDK版本:Java 21

  • JAVA_HOME版本:Java 11

  • Gradle版本:8.11.1

  • 構建腳本使用的是Groovy語言

  • AGP版本:8.10.1(此版本AGP對其它工具的最低版本要求:Gradle 8.11.1JDK 17SDK Build Tools 35.0.0

  • 創建一個純Java的Android項目,它的minSdk設置為21,完整build.gradle文件如下:

    plugins {alias(libs.plugins.android.application)
    }android {namespace 'cn.android666.javaonly'compileSdk 35defaultConfig {applicationId "cn.android666.javaonly"minSdk 21targetSdk 35versionCode 1versionName "1.0"testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"}buildTypes {release {minifyEnabled falseproguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'}}compileOptions {sourceCompatibility JavaVersion.VERSION_1_11targetCompatibility JavaVersion.VERSION_1_11}
    }dependencies {implementation libs.appcompatimplementation libs.materialimplementation libs.activityimplementation libs.constraintlayouttestImplementation libs.junitandroidTestImplementation libs.ext.junitandroidTestImplementation libs.espresso.core
    }
    

    因為是純Java項目,它只有sourceCompatibilitytargetCompatibility ,沒有kotlinjvmTarget屬性了。

2. 1.8和1.8

修改sourceCompatibilitytargetCompatibility 為1.8版本,如下:

compileOptions {sourceCompatibility JavaVersion.VERSION_1_8targetCompatibility JavaVersion.VERSION_1_8
}

MainActivity.java代碼如下:

public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Button button = findViewById(R.id.button);button.setOnClickListener(v -> {Toast.makeText(this, "Hello World!", Toast.LENGTH_SHORT).show();});}
}

運行app,一切正常。查看編譯出來的MainActivity字節碼,如下:
在這里插入圖片描述
顯示字節碼版本為52.0,對應Java 8。

編譯運行時,Build面板中有一些警告信息,如下:

> Task :app:compileDebugJavaWithJavac
Java compiler version 21 has deprecated support for compiling with source/target version 8.
Try one of the following options:1. [Recommended] Use Java toolchain with a lower language version2. Set a higher source/target version3. Use a lower version of the JDK running the build (if you're not using Java toolchain)
For more details on how to configure these settings, see https://developer.android.com/build/jdks.
To suppress this warning, set android.javaCompile.suppressSourceTargetDeprecationWarning=true in gradle.properties.
警告: [options] 源值 8 已過時,將在未來發行版中刪除
警告: [options] 目標值 8 已過時,將在未來發行版中刪除
警告: [options] 要隱藏有關已過時選項的警告, 請使用 -Xlint:-options。
3 個警告

這里的源值8和目標值8,說的就是sourceCompatibilitytargetCompatibility 的值JavaVersion.VERSION_1_8是過時,將在未來發行版中刪除。所以啊,Java 8都已經過時了,我們要趕緊拋棄Java 8了。未來這個值將會被刪掉,那時你想用Java 8都用不了。

JavaVersion.VERSION_1_8即 jdk1.8版本對應Java 8版本。
早期的Java版本都是1.x命令的,1為主版本號,x為次版本號,比如1.5、1.6、1.7、1.8,Java 在 2017 年 9 月發布 Java 9 時,正式啟用了新的版本號方案,只用主版本號,次版本號不要了。可能是由于歷史原因,Gradle API的JavaVersion類中對Java 9和10還是延用了舊的方式,即:VERSION_1_9、VERSION_1_10,到了11就只有主版本號了:VERSION_11。

2. 1.7和1.8

設置sourceCompatibility 為1.7,targetCompatibility 為1.8,如下:

compileOptions {sourceCompatibility JavaVersion.VERSION_1_7targetCompatibility JavaVersion.VERSION_1_8
}

設置sourceCompatibility JavaVersion.VERSION_1_7,則控制了的代碼語法版本為Java 7,但是我的電腦并沒有安裝有JDK 1.7,它是如何實現語法控制的?這是因為現代JDK內置了??多版本語法校驗能力,比如使用JDK21的編譯器進行編譯:

javac -source 1.7 -target 1.7 -bootclasspath /path/to/android-jar Main.java

設置好sourceCompatibilitytargetCompatibility 之后同步Gradle,此時代碼直接報錯了,如下:
在這里插入圖片描述
錯誤提示說:Lambda表達式在語言級別7是不支持的。因為我們把sourceCompatibility設置為JavaVersion.VERSION_1_7,所以在代碼中就不能使用Java 8的特性了,修正代碼:

button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Toast.makeText(MainActivity.this, "Hello World!", Toast.LENGTH_SHORT).show();}
});

把項目Clean一下,然后運行,報錯了,如下:

Execution failed for task ':app:compileDebugJavaWithJavac'.
> Java compiler version 21 has removed support for compiling with source/target version 7.Try one of the following options:1. [Recommended] Use Java toolchain with a lower language version2. Set a higher source/target version3. Use a lower version of the JDK running the build (if you're not using Java toolchain)For more details on how to configure these settings, see https://developer.android.com/build/jdks.Set Java Toolchain to 11
Change Java language level and jvmTarget to 11 in all modules if using a lower level.
Pick a different compatibility level...
Pick a different JDK to run Gradle...
More information...

錯誤翻譯如下:

任務`:app:compileDebugJavaWithJavac`執行失敗。
> Java編譯器版本21已經刪除了對`source/target`版本為7的編譯支持。嘗試以下選項之一:1. [推薦]使用較低語言版本的Java工具鏈。2. 設置更高的`source/target`版本。3. 使用較低版本的JDK來運行構建(如果您沒有使用Java工具鏈)
有關如何配置這些設置的更多詳細信息,請參閱[https://developer.android.com/build/jdks](https://developer.android.com/build/jdks)。設置Java工具鏈為11。
如果使用較低級別,則將所有模塊中的Java語言級別和jvmTarget更改為11。
選擇一個不同的`compatibility`級別。
選擇一個不同的`JDK`來運行Gradle。
更多信息。。。

這個報錯信息里面有很多鏈接是可以點擊的,點擊之后會跳到對應的頁面,展示了對應的解決方案。

錯誤原因已經說的很明白了,IDE使用JDK21來編譯我們的源文件,而我們通過sourceCompatibility JavaVersion.VERSION_1_7來表明我們的源文件是JDK1.7的,JDK21的編譯器已經不支持編譯JDK1.7的源代碼或者輸出JDK1.7目標的字節碼了,所以報錯了。

為什么IDE會選擇使用JDK21來編譯我們的代碼呢?這是因為IDE默認使用運行GradleJDK來編譯我們的代碼。而運行GradleJDK版本是在設置中指定的,具體位置為:File > Settings > Build, Execution, Deployment > Build Tools > Gradle > Gradle JDK,如下圖:
在這里插入圖片描述
Gradle JDK默認使用 GRADLE_LOCAL_JAVA_HOME變量,而這個變量默認指向Android Studio自帶的JetBrains Runtime,在我的版本中,它是21.0.6版本,對應JAVA 21

既然JAVA 21的編譯器不支持編譯JAVA 7的代碼,那我們就可以設置一個低一點的版本來編譯代碼,前面報錯的信息中提供了多種方法,我選擇使用改變工具鏈的方式,代碼如下:

android { compileOptions {sourceCompatibility JavaVersion.VERSION_1_7targetCompatibility JavaVersion.VERSION_1_8}
}java {toolchain {languageVersion = JavaLanguageVersion.of(11)}
}

如上代碼,我們設置了Java工具鏈為Java 11,也就是說Gradle會使用JDK 11的編譯器來編譯我們的代碼,Gradle會自動從電腦中查找JDK11,如果找不到則會自動下載一個。運行項目,一切正常,查看編譯出來的MainActivity字節碼,如下:
在這里插入圖片描述
到這里,我們發現了4個關于Java版本的地方,總結本次運行用到的Java版本:使用JDK 21來運行GradleGradle調用JDK 11的編譯器來把JDK 1.7的源代碼編譯為JDK 1.8的字節碼。

對于工具鏈設置還有一個:

kotlin {jvmToolchain(11)
}

因為創建的這個項目是純Java項目,我使用這個代碼的時候提示說找不到這個kotlin函數,說明這個DSL是Kotlin插件提供的,而我在這個項目中并沒有應用Kotlin插件。

3. 疑問

為什么會有人用低版本寫代碼,然后又編譯為高版本字節碼?而且sourceCompatibility 必須是小于或等于targetCompatibility,如果說我想用JDK 1.8寫代碼,然后你給我編譯為JDK 1.7,這樣才是比較合理的嘛,比如我在代碼中就可以使用Lambda表達式,然后編譯的時候,你把Lambda表達式翻譯為接口以便能在JDK 1.7中運行,這種需求才比較合理嘛!但是這種需求它不允許,因為: sourceCompatibility <= targetCompatibility,如果sourceCompatibility設置大于targetCompatibility ,則運行時就會直接報錯了。

帶著疑問,我問了DeepSeek為什么會有人用低版本寫代碼,然后又編譯為高版本字節碼?答案如下:

  1. ??兼容舊代碼庫,但目標環境已升級至高版本 JVM?

    • 問題??:遺留系統代碼基于 Java 7 開發,無法立即升級語法,但生產環境已升級至 Java 8+ 的 JVM。
    • 解決方案??:
      • 保持源碼兼容 Java 7,避免引入高版本語法導致舊開發環境編譯失敗。
      • 編譯為 Java 8 字節碼,利用高版本 JVM 的性能優化(如元空間替代永久代、編譯器優化等)。
  2. ??依賴庫強制要求高版本運行時環境?

    • 問題??:某些第三方庫(如新版 gRPC、Spring Boot 2.x+)需運行在 Java 8+ 環境,但項目代碼未使用 Java 8 語法。

    • ??解決方案??:

      • 源碼保持 Java 7 兼容性,確保開發工具鏈統一(如 CI/CD 環境仍用 JDK 7 編譯)。
      • 輸出 Java 8 字節碼,滿足依賴庫的最低運行時要求。
  3. 階段性遷移策略?

    • 問題??:大型項目從 Java 7 升級到 Java 8 需分步進行:先確保字節碼兼容新環境,再逐步重構代碼使用新語法。
      ??

    • 解決方案??:

      • 先設置 targetCompatibility=1.8,驗證系統在 Java 8 JVM 的穩定性。
      • 穩定后再逐步修改源碼,啟用 Lambda 等新特性(此時可同步升級 sourceCompatibility=1.8)。
  4. ??規避低版本 JVM 的已知缺陷??

    • ??問題??:Java 7 某些 JVM 實現存在性能或安全漏洞(如 HashCollision 攻擊),但代碼無法立即升級語法。
    • ??解決方案??:
      • 編譯為 Java 8 字節碼并部署到 Java 8+ 環境,直接規避低版本 JVM 的問題。

總結就是:過渡期用 source=1.7, target=1.8 驗證新環境;穩定后升級 source=1.8 啟用新語法。

4. 11和17

設置sourceCompatibility 為11,targetCompatibility 為17,工具鏈設置為21,如下:

android {compileOptions {sourceCompatibility JavaVersion.VERSION_11targetCompatibility JavaVersion.VERSION_17}
}java {toolchain {languageVersion = JavaLanguageVersion.of(21)}
}

Clean項目,然后運行,一切正常,而且這次編譯中沒有報任何警告了。查看字節碼版本:

在這里插入圖片描述
成功把java11的代碼編譯為java17的字節碼。

二、Java與Kotlin混合項目

1. 當前配置

  • Android Studio版本:Android Studio Meerkat Feature Drop | 2024.3.2 Patch 1
  • Gradle JDK版本:Java 21
  • JAVA_HOME版本:Java 11
  • Gradle版本:8.11.1
  • 構建腳本使用的是Kotlin語言
  • AGP版本:8.10.1(此版本AGP對其它工具的最低版本要求:Gradle 8.11.1、JDK 17、SDK Build Tools 35.0.0)
  • Kotlin插件版本:2.0.21
  • 創建一個Kotlin語言的Android項目,它的minSdk設置為21,完整build.gradle.kts文件如下:
plugins {alias(libs.plugins.android.application)alias(libs.plugins.kotlin.android)
}android {namespace = "cn.android666.javaversiontest"compileSdk = 35defaultConfig {applicationId = "cn.android666.javaversiontest"minSdk = 21targetSdk = 35versionCode = 1versionName = "1.0"testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"}buildTypes {release {isMinifyEnabled = falseproguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")}}compileOptions {sourceCompatibility = JavaVersion.VERSION_11targetCompatibility = JavaVersion.VERSION_11}kotlinOptions {jvmTarget = "11"}
}dependencies {implementation(libs.androidx.core.ktx)implementation(libs.androidx.appcompat)implementation(libs.material)implementation(libs.androidx.activity)implementation(libs.androidx.constraintlayout)testImplementation(libs.junit)androidTestImplementation(libs.androidx.junit)androidTestImplementation(libs.androidx.espresso.core)
}

2. 測試

和純Java項目應該是差不多的,所以這里我就測試看有沒有什么需要注意的地方。

targetCompatibilityjvmTarget必須要一致,否則編譯就會報錯,比如:

compileOptions {sourceCompatibility = JavaVersion.VERSION_11targetCompatibility = JavaVersion.VERSION_11
}
kotlinOptions {jvmTarget = "17"
}

編譯報錯信息為:Inconsistent JVM-target compatibility detected for tasks 'compileDebugJavaWithJavac' (11) and 'compileDebugKotlin' (17).,翻譯:檢測到任務‘compileDebugJavaWithJavac’(11)‘compileDebugKotlin’(17)JVM-target兼容性不一致。

沒找到targetCompatibilityjvmTarget 必須要求一致的官方說法,如果必須一致的話那為什么弄兩個屬性,一個不就行了嗎?

工具鏈設置:

java {toolchain {languageVersion.set(JavaLanguageVersion.of(11))}
}kotlin { jvmToolchain(11) }

這里有兩個方式設置Java的工具鏈,第一種針對Java,它來自Android插件。第二種針對Kotlin,它來自Kotlin插件,這兩個插件即build.gradle.kts文件開頭的那兩個,如下:

plugins {alias(libs.plugins.android.application)alias(libs.plugins.kotlin.android)
}

這兩個插件聲明其中一個就可以了,它們都是會同時作用于Java和Kotlin的,第二種方式比較簡潔,所以推薦第二種 。(但是有DeepSeek有提到當指定的工具鏈不存在時,java { toolchain }會自動下載JDK,而kotlin { jvmToolchain }不會,僅用于控制編譯輸出。)

我發現兩個都寫時,可以寫不一樣的,比如:

android {compileOptions {sourceCompatibility = JavaVersion.VERSION_1_7targetCompatibility = JavaVersion.VERSION_1_8}kotlinOptions {jvmTarget = "1.8"}
}java {toolchain {languageVersion.set(JavaLanguageVersion.of(8))}
}kotlin { jvmToolchain(11) }

由于看不到內部運行,不知道Gradle是會統一使用JDK 11來編譯Java和Kotlin的源文件,還是說用JDK 8來編譯Java,用JDK11來編譯Kotlin?

創建項目時sourceCompatibilitytargetCompatibilityjvmTarget 都是默認為11的,但是并沒有指定java工具鏈,所以會默認使用Gradle JDK的版本,對于我的環境就是JDK 21。這里我就有個疑問了,即然目標是11,那為什么不指定工具鏈為11,于是問了DeepSeek,得到的一種說法是JDK 21編譯器更高效,編譯速度更快(尤其增量編譯),只有當默認編譯出錯的時候,再考慮手動添加工具鏈為JDK11,看是否是JDK21編譯的問題,比如某些庫可能在JDK21下行為異常,又比如KAPTKotlin注解處理器)在JDK21下存在Bug

總結就是沒問題就用默認,有問題再嘗試指定工具鏈。

驗證工具鏈的使用:

  • 如何證明默認用的是JDK21,當不設置工具鏈時,設置sourceCompatibility = JavaVersion.VERSION_1_7時,運行時報錯提示:“Java compiler version 21 has removed support for compiling with source/target version 7.”,這說明是在使用Java 21的編譯器,這個版本正好和Gradle JDK的版本一致。

  • 如何證明下面兩種方式都能修改工具鏈:

    java {toolchain {languageVersion.set(JavaLanguageVersion.of(17))}
    }kotlin { jvmToolchain(11) }
    

    和上一個例子一樣,設置sourceCompatibility = JavaVersion.VERSION_1_7,運行時就會報錯,于是分別單獨使用上述兩種方式設置低版本的工具鏈,然后運行都正常了,說明兩種方式都是OK的。

  • 如何證明兩種方式同時使用時,到底用哪一個?當我只設置languageVersion.set(JavaLanguageVersion.of(17))時,在Gradle控制面板執行:clean,確保編譯的代碼被清空,然后再執行編譯代碼:app:compileDebugJavaWithJavac --info,查看控制臺,如下:
    在這里插入圖片描述
    可看到,使用的工具鏈是Java 17。
    在不刪除任何配置的同時添加kotlin { jvmToolchain(11) },然后執行相同操作,即先clean,然后再編譯代碼,結果如下:
    在這里插入圖片描述
    這是否可以證明當同時使用兩種方式設置工具鏈時,不論兩種方式設置的版本是否相同,java和kotlin代碼都只會使用同一個版本的工具鏈,且使用kotlin { jvmToolchain() }中設置的版本。

類似的命令:app:compileDebugKotlin --info,但是這個命令并不會輸出工具鏈版本。

總之,通過前面的例子,最少能證明只設置kotlin { jvmToolchain() }時,它也是能作用于Java的。所以,以后寫代碼盡量用kotlin的方式來設置工具鏈,java的那個設置方式比較長,也不好記。

各種Java版本總結

android {compileOptions {sourceCompatibility = JavaVersion.VERSION_11targetCompatibility = JavaVersion.VERSION_11}kotlinOptions {jvmTarget = "11"}
}java {toolchain {languageVersion.set(JavaLanguageVersion.of(11))}
}kotlin { jvmToolchain(11) }

畫圖分析如下:
在這里插入圖片描述
Android中的各種Java版本如上圖所示,解釋如下:

  • 需要使用JDK來運行Gradle

  • 在命令行運行Gradle,使用的JDK會優選使用JAVA_HOME環境變量,如果沒有這個變量,則使用系統默認的,即從PATH環境變量中找JDK來運行,找到哪個就用哪個,找不到就運行不了。Gradle還分啟動器進程和守護進程,啟動器進程由JAVA_HOME或系統默認JDK運行,然后還會再啟動一個守護進程,如果有在gradle.properties中指定org.gradle.java.home,則用這個屬性指定的JDK來運行守護進程,如果沒指定這個屬性,則使用和啟動器進程一樣的JDK來運行守護進程。

  • 如果是Android Studio調用Gradle,比如點擊運行按鈕,點擊Build菜單中的各種構建命令,在Gradle面板中執行Gradle任務等,這些都是屬于Android Studio去調用Gradle來執行任務,它會使用的設置里面的Gradle JDK來運行Gradle。

  • Gradle調用javac來編譯java源代碼,用kotlinc來編譯kotlin源代碼,javac是jdk里面的,kotlinc是kotlin里面的,但是它也是要依賴jdk來進行編譯的,而這個jdk默認會使用Gradle JDK,如果你想用別的版本的JDK來編譯代碼,不建議修改Gradle JDK,因為Gradle JDK用于運行Gradle,而且有時候你還改不了它,比如AGP 8.0要求運行它的JDK最少是JDK 17版本,如果此時你想使用JDK 11來編譯代碼,但是你的AGP又是8.0或更高的版本,那就不能把Gradle JDK修改為JDK 11了。所以,推薦的做法是設置工具鏈,如果是純java項目,可以使用java { toolchain }來設置工具鏈,它是在Gradle的java插件中定義的,雖然我們的項目只應用了Android插件,但是Android插件內部依賴并隱式應用了 Java 插件??。如果是kotlin項目,則可以使用java { toolchain }kotlin { jvmToolchai }來設置工具鏈,這兩個設置其中一個即可,它們都可以同時作用于java和kotlin。kotlin { jvmToolchain }是在kotlin插件中定義的,所以在純java項目中沒應用這個插件就用不到這個了。另外DeepSeek有提到java { toolchain }會自動下載工具鏈(如果系統找不到指定的工具鏈),而kotlin { jvmToolchai }不會自動下載工具鏈,僅用于控制編譯輸出(有待驗證)。

  • 運行Gradle的JDK理論上來說能高一點就高一點,因為高一點的JDK運行效率一般會高一些。

  • Java工具鏈的版本理論上來說也是能高一點就高一點,因為效率高,比如編譯速度快。一般來說保持默認使用Gradle JDK即可。

  • 在使用javac編譯java代碼時,通過 compileOptions { targetCompatibility }可以指定編譯為哪個版本的字節碼。

  • 在使用kotlinc編譯kotlin代碼時,通過 kotlinOptions { jvmTarget}可以指定編譯為哪個版本的字節碼。

  • compileOptions { sourceCompatibility } 的作用是指定 Java 源代碼的語法版本(即編譯時支持的 Java 語言特性)。語言特性指的是什么?它是指在 Java 代碼中可以使用的語法規則、語義結構和關鍵字,這些特性是由 Java 不同版本引入的新功能。常見的語言特性及其 Java 版本如下:

    Java 版本引入的語言特性示例
    Java 5泛型、增強 for 循環、自動裝箱List<String> list = new ArrayList<>();
    Java 7try-with-resourcesswitch 支持字符串、二進制字面量try (FileInputStream fis = ...) {}
    Java 8Lambda 表達式、方法引用、默認接口方法、Stream API(a, b) -> a + b
    Java 9模塊系統(module-info.java)、私有接口方法module my.module {}
    Java 10局部變量類型推斷(varvar list = new ArrayList<String>();
    Java 14switch 表達式、record 類型(預覽)switch (x) { case 1 -> "one"; }
    Java 16+record 正式引入record Point(int x, int y) {}

sourceCompatibility 只是限制語言特性,它并不限制API,API是指標準類庫里面的類,比如Java 8引入的新API:

LocalDate.now();

語言特性是由JDK編譯器控制的,而APIandroid.jar提供,使用哪個版本的android.jar進行編譯,取決于compileSdk

假設我們把sourceCompatibility 設置為Java 7targetCompatibility設置為JAVA 11,則在寫代碼的時候,如果使用超出Java 7的語言特性,則相關代碼直接顯示紅色,比如我使用了var,和Lambda,var是Java10才有的語言特性,Lambda是Java8才有的語言特性,所以使用這些會直接報紅色,如下:
在這里插入圖片描述
而對于使用高版本API,它是能調用出來的,導包也沒問題,只是在你代碼下方顯示紅色波浪線,比如我使用Java 8中的LocaDate類:
在這里插入圖片描述
把鼠標移到報錯上面會提示錯誤原因,如下:
在這里插入圖片描述
有的API報錯還不一樣,如下:
在這里插入圖片描述
提示的錯誤信息為:
在這里插入圖片描述
總結如下:

  • 調用LocalDate.now()提示:Call requires API level 26 (current min is 21)
  • 調用List.of(1, 2, 3)提示:Static interface method calls are not supported at language level ‘7’

由于我的sourceCompatibility 設置為Java 7,而LocalDate.now()Java8出的,List.of()Java9出的,報錯能理解,但是為什么報的錯不一樣呢?這是因為兩種不同的兼容性檢查機制?:

  1. LocalDate.now() 的報錯:??Android API級別檢查?
    • 觸發機制??:Android構建工具(如Lint)在編譯時會對代碼進行??API級別校驗??,發現LocalDateAPI 26引入的類,而你的minSdk=21,我們在Android官方文檔中查看LocalDate也能看到它是API 26引入的。
  2. List.of() 的報錯:??Java語言級別檢查?
    • 觸發機制??:Java編譯器(javackotlinc)在編譯時根據sourceCompatibility=1.7檢查語法,發現List.of()Java 9的語法特性,雖然說List.of() 是一個API,但是它是使用Java 9的語言特性的:接口靜態方法

我設置minSdk 26,然后 LocalDate.now() 就不報錯了,而List.of()依然報錯,這充分說明sourceCompatibility只是限制語法,并不限制API。報錯時提示Static interface method calls are not supported at language level ‘7’,說的就是Java 7不支持靜態接口方法,這指的就是語法問題,而非API問題。

來自官方的Java版本

Android build 中的 Java 版本

此章節內容完全來自于官網:https://developer.android.google.cn/build/jdks?hl=zh-cn
無論您的源代碼是用 Java 還是 Kotlin 編寫的,您都必須在多個位置為 build 選擇 JDK 或 Java 語言版本。
在這里插入圖片描述
還得是官方啊,一圖就把所有Java版本總結出來了,如上圖,主要分成3塊內容,左、中、右。

  • 左邊是Source,即各種源代碼
  • 中間為 “Versions in Build Files”,即 “在構建文件里面的Java版本”,也就是聲明在build.gradle.kts文件中的Java版本,有5個,分別為:
    • Kotlin jvmTarget 用于設置Kotlin源代碼編譯后的字節碼版本。
    • targetCompatibility JDK 用于設置Java源代碼編譯后的字節碼版本。
    • sourceCompatibility JDK 用于在編譯時指定Java源代碼的版本,同時也會用作 IDE 代碼輔助和 lint 的默認選項,所以寫代碼的時候如果有錯誤就會立馬報錯提示,而無需等到編譯時期。
    • Toolchain JDK 用于設置工具鏈的版本,比如用什么版本的JDK執行編譯操作。用什么版本的JDK運行單元測試等。
    • JDK API,它由構建文件中的 compileSdk指定,指定的是Android的編譯版本,不同的Android版本提供不同的版本的JDK API。
  • 右邊是運行GradleJDK和運行Android StudioJDK。所以,加起來一共就有7個JDK版本了。
  • 源代碼依賴于JDK API,而它由compileSdk指定。
  • 單元測試(Unit Tests)的運行使用Toolchain JDK
  • Kotlin jvmTargettargetCompatibility JDKsourceCompatibility JDK 在不設置的情況下,默認為Toolchian JDK,而Toolchian JDK本身也沒置的情況下,Toolchian JDK默認為Gradle JDK。對于Gradle JDK的設置,又分兩個叉,一個是用于Android Studio構建,它定義在Android Studio的設置中,Android Studio本身又運行在JetBrains Runtime JDK之上,另一個用于命令行構建,它定義在gradle.properties文件中的org.gradle.java.home屬性中,如果該屬性沒設置的話,默認使用JAVA_HOME

術語庫

  • Java 開發套件 (JDK),包含:

    • 工具,例如編譯器、性能分析器和歸檔創建工具。 這些文件會在構建過程中在后臺使用,以創建您的應用。
    • 包含您可以從 Kotlin 或 Java 源代碼調用的 API 的庫。請注意,并非所有功能都適用于 Android 設備。
    • Java 虛擬機 (JVM),一種用于執行 Java 應用的解釋器。您可以使用 JVM 運行 Android Studio IDE 和 Gradle 構建工具。JVM 不會在 Android 設備或模擬器上使用。
  • JetBrains 運行時 (JBR),JetBrains Runtime (JBR) 是一種增強型 JDK,隨 Android Studio 分發。 它包含多項優化,可在 Studio 和相關 JetBrains 產品中使用,但也可用于運行其他 Java 應用。

如何選擇用于運行 Android Studio 的 JDK?

我們建議您使用 JBR 運行 Android Studio。該插件隨 Android Studio 一起部署并用于測試 Android Studio,其中包含一些增強功能,可確保最佳 Android Studio 使用體驗。為此,請勿設置 STUDIO_JDK 環境變量。

Android Studio 的啟動腳本會按以下順序查找 JVM

  1. STUDIO_JDK 環境變量
  2. studio.jdk 目錄(在 Android Studio 發行版中)
  3. Android Studio 發行版中的 jbr 目錄(JetBrains 運行時)。推薦。
  4. JDK_HOME 環境變量
  5. JAVA_HOME 環境變量
  6. PATH 環境變量中的 java 可執行文件

如何選擇運行 Gradle build 的 JDK?

如果您使用 Android Studio 中的按鈕運行 Gradle,則 Android Studio 設置中設置的 JDK 將用于運行 Gradle。如果您在終端(Android Studio 內或外)中運行 Gradle,則 JAVA_HOME 環境變量(如果已設置)決定了哪個 JDK 運行 Gradle 腳本。如果未設置 JAVA_HOME,則會對 PATH 環境變量使用 java 命令。

為了獲得最一致的結果,請務必將 JAVA_HOME 環境變量和 Android Studio 中的 Gradle JDK 配置設置為同一 JDK。

注意 :如果您使用 IDE 右鍵點擊并選擇運行突出顯示的命令,在 Android Studio 終端中運行 Gradle 命令,則它會使用 Android Studio 設置中的 JDK,而不是 JAVA_HOME。

運行 build 時,Gradle 會創建一個名為 “守護程序” 的進程來執行實際 build。只要 build 使用的是相同的 JDK 和 Gradle 版本,就可以重復使用此過程。重復使用守護程序可縮短啟動新 JVM 和初始化構建系統的時間。

如果您使用不同的 JDK 或 Gradle 版本啟動 build,系統會創建其他守護程序,從而消耗更多 CPU 和內存。

提示: 同時處理多個項目時,請盡可能在其 gradle-wrapper.properties 文件中指定相同的 Gradle 版本,以減少創建的 Gradle 守護程序數量。

Android Studio 中的 Gradle JDK 配置

如需修改現有項目的 Gradle JDK 配置,請依次前往 File(或在 macOS 上依次前往 Android Studio) > Settings > Build, Execution, Deployment > Build Tools > Gradle,打開 Gradle 設置。Gradle JDK 下拉菜單包含以下可供選擇的選項:

  • 宏(例如 JAVA_HOMEGRADLE_LOCAL_JAVA_HOME
  • vendor-version 格式的 JDK 表條目(例如 jbr-17),存儲在 Android 配置文件中
  • 下載 JDK
  • 添加特定 JDK
  • 從操作系統的默認 JDK 安裝目錄本地檢測到的 JDK\

所選選項存儲在項目的 .idea/gradle.xml 文件中的 gradleJvm 選項中,其 JDK 路徑解析用于在通過 Android Studio 啟動時運行 Gradle。
在這里插入圖片描述
這些宏支持動態選擇項目 JDK 路徑:

  • JAVA_HOME:使用同名的環境變量
  • GRADLE_LOCAL_JAVA_HOME:使用 .gradle/config.properties 文件中的 java.home 屬性,默認為 JetBrains 運行時。

所選的 JDK 用于運行 Gradle build,并在修改 build 腳本和源代碼時解析 JDK API 引用。請注意,在修改和構建源代碼時,指定的 compileSdk 會進一步限制可用的 Java 符號。

注意 :在大多數情況下,我們建議使用 GRADLE_LOCAL_JAVA_HOME,這是新創建的項目的默認值。這樣,您無需先打開項目,即可定義特定于項目的 JDK。

請務必選擇高于或等于您在 Gradle build 中使用的插件所使用的 JDK 版本的 JDK 版本。如需確定 Android Gradle 插件 (AGP) 的最低要求 JDK 版本,請參閱版本說明中的兼容性表格。

例如,Android Gradle 插件版本 8.x 需要 JDK 17。如果您嘗試運行使用較低版本 JDK 的 Gradle build,系統會報告如下消息:

An exception occurred applying plugin request [id: 'com.android.application']
> Failed to apply plugin 'com.android.internal.application'.> Android Gradle plugin requires Java 17 to run. You are currently using Java 11.Your current JDK is located in /usr/local/buildtools/java/jdkYou can try some of the following options:- changing the IDE settings.- changing the JAVA_HOME environment variable.- changing `org.gradle.java.home` in `gradle.properties`.

我可以在 Java 或 Kotlin 源代碼中使用哪些 Java API?

Android 應用可以使用 JDK 中定義的部分 API,但不能使用所有 API。Android SDK 在其可用 API 中定義了許多 Java 庫函數的實現。compileSdk 屬性用于指定在編譯 Kotlin 或 Java 源代碼時要使用的 Android SDK 版本。

android {...compileSdk = 33
}

每個版本的 Android 都支持特定版本的 JDK 以及其可用 Java API 的一部分。如果您使用的 Java API 在 compileSdk 中可用,但在指定的 minSdk 中不可用,則您或許可以通過稱為脫糖的流程在較低版本的 Android 中使用該 API。如需了解受支持的 API,請參閱通過脫糖提供的 Java 11 及更高版本 API。

您可以使用此表格確定每個 Android API 支持哪個 Java 版本,以及在哪里可以詳細了解可用的 Java API。

AndroidJava支持的 API 和語言功能
14 (API 34)17核心庫
13 (API 33)11核心庫
12 (API 32)11Java API
11 及更低版本Android 版本

哪個 JDK 會編譯我的 Java 源代碼?

Java 工具鏈 JDK 包含用于編譯任何 Java 源代碼的 Java 編譯器,此 JDK 還會在構建期間運行 javadoc 和單元測試。

工具鏈默認為用于運行 Gradle 的 JDK。如果您使用默認設置并在不同的計算機(例如本地計算機和單獨的持續集成服務器)上運行 build,那么如果使用不同的 JDK 版本,build 的結果可能會有所不同。

如需創建更一致的 build,您可以明確指定 Java 工具鏈版本。指定此屬性:

  • 在運行 build 的系統上查找兼容的 JDK。
    - 如果不存在兼容的 JDK(并且已定義工具鏈解析器),則下載一個。
  • 公開工具鏈 Java API,以便從源代碼進行調用。
  • 使用 Java 語言版本編譯 Java 源代碼。
  • sourceCompatibilitytargetCompatibility 的默認值。

我們建議您始終指定 Java 工具鏈,并確保已安裝指定的 JDK,或者將工具鏈解析器添加到 build 中。

無論您的源代碼是用 Java 還是 Kotlin 編寫的,您都可以指定工具鏈。在模塊的 build.gradle(.kts) 文件的頂層指定工具鏈。

java {toolchain {languageVersion = JavaLanguageVersion.of(17)}
}

如果您的源代碼是 Kotlin、Java 或兩者的混合,此方法適用。

工具鏈 JDK 版本可以與用于運行 Gradle 的 JDK 相同,但請注意,它們的用途不同。

我可以在 Java 源代碼中使用哪些 Java 語言源代碼功能?

sourceCompatibility 屬性決定了在編譯 Java 源代碼期間可用的 Java 語言功能。它不會影響 Kotlin 源代碼。

在模塊的 build.gradle(.kts) 文件中指定 sourceCompatibility,如下所示:

android {compileOptions {sourceCompatibility = JavaVersion.VERSION_17}
}

如果未指定,此屬性默認為 Java 工具鏈版本。如果您不使用 Java 工具鏈,則默認使用 Android Gradle 插件選擇的版本(例如 Java 8 或更高版本)。

注意 :從 Android Studio Giraffe 開始,在導入項目時,sourceCompatibility 選項還會在編寫 Java 源代碼時用作 IDE 代碼輔助和 lint 的默認選項。某些 Java 語言功能需要庫支持,并且在 Android 上不可用。compileSdk 選項決定了哪些庫可用。 其他功能(例如 switch 表達式)只需要 Java 編譯器,并且適用于 Android。

在編譯 Kotlin 或 Java 源代碼時,可以使用哪些 Java 二進制功能?

targetCompatibilityjvmTarget 屬性分別決定為編譯的 JavaKotlin 源代碼生成字節碼時使用的 Java 類格式版本。

在添加等效的 Java 功能之前,就已經存在一些 Kotlin 功能。早期的 Kotlin 編譯器必須自行創建表示這些 Kotlin 功能的方法。其中一些功能后來被添加到了 Java 中。在較高版本的 jvmTarget 中,Kotlin 編譯器可能會直接使用 Java 功能,這可能會帶來更好的性能。

不同版本的 Android 支持不同的 Java 版本。您可以通過提高 targetCompatibilityjvmTarget 來使用其他 Java 功能,但這可能會迫使您也提高最低 Android SDK 版本,以確保該功能可用。

請注意,targetCompatibility 必須大于或等于 sourceCompatibility。在實踐中,sourceCompatibilitytargetCompatibilityjvmTarget 通常應使用相同的值。您可以按如下方式進行設置:

android {compileOptions {sourceCompatibility = JavaVersion.VERSION_17targetCompatibility = JavaVersion.VERSION_17}kotlinOptions {jvmTarget = "17"}
}

如果未指定,這些屬性默認為 Java 工具鏈版本。如果您未使用 Java 工具鏈,則默認值可能會有所不同,并導致構建問題。因此,我們建議您始終明確指定這些值或使用 Java 工具鏈。

脫糖

sourceCompatibilitytargetCompatibility實現了低版本寫代碼高版本輸出,但是這并不常用,而高版本寫代碼低版本輸出呢,這才是常用的,而且我們Adnroid開發可以說天天都在用,那這是怎么實現的?比如Android 5Adnroid 6系統原生只支持到Java 7。我們寫Android項目時,對于兼容性,一般來說指定minSdk就可以了,比如minSdk設置為21,對應為Android 5,也就是說這個項目需要兼容的最低版本是Android 5,假設我們把targetCompatibilityjvmTarget設置為11,那生成的字節碼是Java 11版本的字節碼,為什么可以在Android 5上運行?Android 5系統原生只支持到Java 7啊,為什么運行沒問題?這是因為Android并不是直接運行.class字節碼文件的,Android運行的是dex,所以在Java 11字節碼文件轉換為dex的時候,轉換工具就動了手腳,它會根據你聲明的minSdk來轉換為對應Java版本可以支持的dex,這種操作叫“脫糖”,比如你在代碼中使用了Lambda表達式,這是Java 8的特性,脫糖會把Lambda轉換為接口的對應實現,簡單理解就是:本來你用的是高版本的特性實現的一些功能,脫糖就是給你轉換為低版本實現的對應功能。

這篇文章已經很長了,關于脫糖的更多知識可以查看我的另一篇文章:https://blog.csdn.net/android_cai_niao/article/details/148627756

Java SE支持路線圖

來自Oracle官方網站:https://www.oracle.com/java/technologies/java-se-support-roadmap.html
在這里插入圖片描述
表格說明:

  1. ??版本 (Release)??

    • ??LTS??:長期支持版本(Long-Term Support),Oracle提供5年以上支持
    • ??非LTS??:過渡版本,僅支持6個月(企業環境不推薦)
  2. ??GA日期 (GA Date)??
    正式發布可用日期(General Availability)

  3. ??首要支持截止 (Premier Support Until)??

    • ??核心支持期??:免費提供安全更新、錯誤修復和技術支持
    • ??免費用戶注意??:社區用戶免費更新僅到此日期
  4. ??擴展支持截止 (Extended Support Until)??

    • ??付費支持期??:需購買Oracle商業許可(費用高昂)
    • ??特殊豁免??:
      • Java 8擴展支持免費豁免至2030年12月
      • Java 11擴展支持免費豁免至2032年1月
      • 豁免的意思就是說Oracle對指定版本的個人/開發者枉開一面,免費延長支持,但企業商用則需要從截止日期起付費。
  5. ??持續支持 (Sustaining Support)??
    無時間限制的付費支持(不包含新功能或安全更新)

這個解析來自DeepSeek,不知道對不對,如果對的話,那Java8和11的免費支持都已經到期了,而Java 17也即將在2026年到期,Java 21在2028年到期,好像都沒多久啊!!

不過做Android開發好像也不用關心這個,因為Android用的并不是Oracle JDK,用的是OpenJDK,這個是可以隨便用且沒有限制,不需要給Oracle付錢。但是就是說停止支持意味著這個版本更容易過時,所以,如果可能的話,還是盡快切換到新版本。

命令行運行gradle時Java版本不對的問題

我當前使用的Android Studio為截止目前的最新版本:Android Studio Meerkat Feature Drop | 2024.3.2 Patch 1
在這里插入圖片描述
創建一個Android項目,然后運行到Android手機上,這是沒問題的,編譯/運行都完全OK,然后在Terminal中執行:.\gradlew tasks命令,結果如下:

* What went wrong:
An exception occurred applying plugin request [id: 'com.android.application', version: '8.10.1']
> Failed to apply plugin 'com.android.internal.application'.> Android Gradle plugin requires Java 17 to run. You are currently using Java 11.

這里只貼了部分輸出,顯示應用AGP 8.10.1插件需要使用Java 17,而當前是Java 11。

這里提及這個問題,是想說,還有一個地方可以設置java版本,在gradle.properties文件中最后添加一行:

org.gradle.java.home=C\:\\Program Files\\Java\\jdk-17

然后再執行.\gradlew tasks命令就正常了。

即使我不設置org.gradle.java.home,我在Android Studio的Gradle面板中執行tasks任務又是OK,這個問題可以在我的另一篇文章中找到答案,查看該文章的驗證Gradle使用的JDK版本段落:https://blog.csdn.net/android_cai_niao/article/details/148588362

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/96534.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/96534.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/96534.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

ubuntu新增磁盤擴展LV卷

登錄平臺 login as: wqbboy wqbboy172.17.2.86s password: Welcome to Ubuntu 22.04.5 LTS (GNU/Linux 5.15.0-153-generic x86_64)* Documentation: https://help.ubuntu.com* Management: https://landscape.canonical.com* Support: https://ubuntu.com/proSyst…

Day 16: GAN生成對抗網絡專項 - 從博弈論到藝術創作的完整之旅

Day 16: GAN生成對抗網絡專項 - 從博弈論到藝術創作的完整之旅 ?? 學習目標: 深度掌握生成對抗網絡理論與實踐,從博弈論基礎到風格遷移應用的完整技術棧 ? 學習時長: 6小時深度學習 (理論3小時 + 實踐3小時) ?? 技術棧: PyTorch + 數學推導 + 經典架構 + 實戰應用 ?? 核…

《QT 108好類》之16 QComboBox類

《QT 108好類》之16 QComboBox類QT 108好類之16 QComboBox類QComboBox類特性和應用場景QComboBox類繼承關系QComboBox類使用1 簡單使用2 表單輸入3 使用自定義模型和視圖4 完全自定義彈出窗口QComboBox類類使用效果QT 108好類之16 QComboBox類 QComboBox是 常用的下拉框&#…

項目模塊劃分

項目模塊劃分 服務端模塊&#xff1a; 持久化數據管理中心模塊 在數據管理模塊中管理交換機&#xff0c;隊列&#xff0c;隊列綁定&#xff0c;消息等部分數據數據。 \1. 交換機管理&#xff1a; a. 管理信息&#xff1a;名稱&#xff0c;類型&#xff0c;是否持久化標志&#…

小白也能看懂!OpenCV 從零開始安裝配置全教程(包含Windows / Ubuntu / 樹莓派)系統詳細操作配置教程

小白也能看懂&#xff01;OpenCV 從零開始安裝配置全教程&#xff08;包含Windows / Ubuntu / 樹莓派&#xff09;系統詳細操作配置教程 摘要 本教程是面向“小白也能懂”的OpenCV安裝與配置全攻略&#xff0c;涵蓋Windows、Ubuntu和樹莓派三大平臺&#xff0c;真正實現“從零…

【華為云】容器鏡像服務 SWR 詳解:從上傳下載到 ModelArts 應用

前言 華為云容器鏡像服務&#xff08;Software Repository for Container&#xff0c;簡稱 SWR&#xff09;是華為云提供的企業級容器鏡像倉庫服務。它支持 Docker 鏡像的存儲、管理和分發&#xff0c;為容器化應用提供安全可靠的鏡像托管服務。本文將詳細介紹 SWR 的核心功能…

計算機網絡知識點梳理(一)概述:組成、發展、性能、體系結構等

目錄 一、互聯網 &#xff08;1&#xff09;特點 &#xff08;2&#xff09;網絡的組成 &#xff08;3&#xff09;網絡、互連網、因特網 &#xff08;4&#xff09;互聯網發展的三個階段 &#xff08;5&#xff09;標準化 &#xff08;6&#xff09;組成 二、計算機網…

不同行業視角下的數據分析

聲明&#xff1a;以下部分內容含AI生成 基于行業維度來劃分數據分析崗位&#xff0c;可以幫助我們更好地理解不同行業對數據分析技能、業務知識和職業發展的獨特要求。 目錄 一、總體框架&#xff1a;為什么行業維度如此重要&#xff1f; 二、主要行業劃分及詳細講解 1. 互聯…

「CTF」青少年CTF·雛形系統

題目&#xff1a; 解題過程 嘗試隨便輸入點什么&#xff0c;沒有結果 使用dirsearch掃描網址目錄 可以看到有掃描到一個www.zip&#xff0c;zip文件大概率有需要的東西 網址后加上www.zip就能對該文件進行下載 文件解壓縮后如下 打開qsnctf.php&#xff0c;代碼內容如下 <…

Java實戰項目演示代碼及流的使用

project 準備牌->洗牌->發牌 import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.TreeSet;public class PokerGameplus {static HashMap<Integer,String> hs new HashMap<>();static ArrayList<Int…

使用 OpenLayers + 高德瓦片源實現旅游足跡地圖

作為一個熱愛旅行的開發者&#xff0c;我一直想要一個能夠記錄和展示自己旅游足跡的功能。市面上雖然有很多地圖應用&#xff0c;但大多功能復雜&#xff0c;而我只需要一個簡單直觀的方式來標記去過的地方和想去的地方。 于是我決定在自己的個人網站上實現一個旅游足跡地圖功…

Redis基礎(含常用命令等以快速入門)

一、初步認識 1、NoSQL SQL 關系型數據庫&#xff08;表結構&#xff0c;強一致&#xff09;NoSQL 非關系型數據庫&#xff08;靈活結構&#xff0c;最終一致&#xff0c;水平擴展爽&#xff09; 維度SQL&#xff08;關系型&#xff09;NoSQL&#xff08;非關系型&#xf…

OSPF特殊區域、路由匯總及其他特性

OSPF路由器需要同時維護域內路由、域間路由、外部路由信息數據庫。當網絡規模不斷擴大時&#xff0c;LSDB規模也不斷增長。如果某區域不需要為其他區域提供流量中轉服務&#xff0c;那么該區域內的路由器就沒有必要維護本區域外的鏈路狀態數據庫。OSPF通過劃分區域可以減少網絡…

在緩存Cacheable注解中Key值如何使用常量

1.在常量類中定義商品緩存空間和商品緩存KEY public interface CacheConstants {/*** Goods Cache Name*/String QNA_GOODS_CACHE "qna-goods";/*** Goods Cache key*/String QNA_GOODS_CACHE_KEY "qna_goods:";/*** Order Cache Name*/String QNA_ORDER…

sklearn聚類

在此將sklearn官網的一張關于聚類算法比較的圖片放過來。 下面的表格是根據sklearn官網翻譯而來。 方法名稱 參數 可擴展性 應用場景 幾何度量(距離) MiniBatchKMeans 簇的數量 非常適合處理大量樣本和中等數量的簇(使用MiniBatch時) 通用型,適用于簇大小均勻、幾何形狀平…

Recharts:React圖表庫,組件化設計助力高效數據可視化開發

你寫前端項目時有沒有卡過數據可視化的坑&#xff1f;比如要做個用戶增長折線圖&#xff0c;查了半天原生 JS 教程&#xff0c;寫了幾十行代碼&#xff0c;結果要么坐標軸對不上&#xff0c;要么數據渲染不出來&#xff1b;或者用了某個圖表庫&#xff0c;文檔全是英文&#xf…

Java 中String類的常用方法

Java 中的 String 類提供了豐富的方法用于字符串操作&#xff0c;以下是最常用的一些方法分類總結&#xff1a; 一、獲取字符串信息length()&#xff1a;返回字符串長度&#xff08;字符個數&#xff09; String s "hello"; int len s.length(); // len 5charAt(i…

【記錄】Docker|Docker內部訪問LInux主機上的Ollama服務

部分內容參考自&#xff1a;使得 docker 容器內部可以訪問宿主機的 ollama 服務_docker 訪問 ollama-CSDN 博客&#xff0c;補充添加了更多的細節&#xff0c;也補充了一個更加簡單的方案。 我測試的系統版本&#xff1a;Ubuntu 24.04.2 LTS noble&#xff0c;查看方式是指令 l…

數據庫物理外鍵與邏輯外鍵全解析

一、核心概念 1. 物理外鍵 (Physical Foreign Key) 物理外鍵是數據庫層面通過語法明確創建的外鍵約束。它是由數據庫管理系統&#xff08;DBMS&#xff09;本身&#xff08;如 MySQL, PostgreSQL, Oracle&#xff09;來強制實現的。 它是什么&#xff1a;數據庫表結構的一部分&…

Vue3入門到實戰,最新版vue3+TypeScript前端開發教程,創建Vue3工程,筆記03

筆記03 一、創建Vue3項目 1.1、創建方式 使用vue-cli創建使用vite創建&#xff08;推薦&#xff09;Vue3官網創建項目文檔 兩種創建方式&#xff0c;推薦使用第二種。vue-cli是基于webpack實現的&#xff0c;vite是新一代前端構建工具。 2.1、vue3項目結構