[英]Switching between different JDK versions in Windows
我正在处理几个项目,其中一些项目使用不同的 JDK。 在 JDK 版本之间切换并不方便。 所以我想知道是否有任何简单的方法可以改变它?
我找到了两种方法,应该可以解决这个问题,但它不起作用。
第一个解决方案是创建一个像这样的 bat 文件:
@echo off
echo Setting JAVA_HOME
set JAVA_HOME=C:\Program Files\Java\jdk1.7.0_72
echo setting PATH
set PATH=C:\Program Files\Java\jdk1.7.0_72\bin;%PATH%
echo Display java version
java -version
pause
在运行这个 bat 之后,我看到了正确的 Java 版本。 但是当我关闭这个 CMD 并打开一个新的并输入“java -version”时,它说我还有 1.8.0_25。 所以它不起作用。
我发现的第二个解决方案是这个站点的一个应用程序。 而且它也不起作用。 与第一个解决方案中的效果相同。
有任何想法吗? 因为通过以下方式更改 JAVA_HOME 和 PAHT:Win + Pause -> Advanced System Settings -> Environment Variables -> 并编辑这些变量,是一种糟糕的方式......
set
命令仅适用于当前终端。 要永久设置系统或用户环境变量,您可以使用setx
。
setx JAVA_HOME "C:\Program Files\Java\jdk1.7.0_72" /m
/m
选项用于设置变量系统范围(而不仅仅是当前用户)。 终端必须以管理员身份运行才能使用此选项。
该变量将在所有新终端窗口中可用,但在当前窗口中不可用。 如果您还想在同一窗口中使用路径,则需要同时使用set
和setx
。
如果您只将%JAVA_HOME%
放在那里,而不是完整的 JDK 路径,则可以避免操作PATH
变量。 如果您更改JAVA_HOME
, PATH
也将被更新。
还有一些环境变量编辑器可以替代繁琐的 Windows 环境变量设置。 请参阅超级用户上的“ 在 Windows 7 中是否有一种方便的方式来编辑 PATH? ”。
如果有人想在每个新的命令窗口中频繁切换,那么我将使用以下方法。
命令提示符版本:
使用以下代码创建批处理文件。 您可以使用 if 和 else 块添加 n 个版本。
@echo off
if "%~1" == "11" (
set "JAVA_HOME=C:\Software\openjdk-11+28_windows-x64_bin\jdk-11"
) else (
set "JAVA_HOME=C:\Program Files\Java\jdk1.8.0_151"
)
set "Path=%JAVA_HOME%\bin;%Path%"
java -version
将此批处理文件另存为 SJV.bat 并将此文件位置添加到计算机的 Path 环境变量中。 所以现在 SJV 将充当“切换 Java 版本”的命令。
现在打开新的命令窗口,只需键入SJV 11
它将切换到 Java 11。键入SJV 8
它将切换到 Java 8。
PowerShell 版本
使用以下代码创建 powershell(ps1) 文件。 您可以使用 if 和 else 块添加 n 个版本。
If($args[0] -eq "11")
{
$env:JAVA_HOME = 'C:\Software\openjdk-11+28_windows-x64_bin\jdk-11'
}else{
$env:JAVA_HOME = 'C:\Program Files\Java\jdk1.8.0_151'
}
$env:Path = $env:JAVA_HOME+'\bin;'+$env:Path
java -version
将此脚本文件另存为 SJV.ps1 并将此文件位置添加到计算机的 Path 环境变量中。 所以现在 SJV 将充当“切换 Java 版本”的命令。
现在打开新的 powershell 窗口,只需键入SJV 11
它将切换到 Java 11。键入SJV 8
或SJV
它将切换到 Java 8。
我希望这对想要经常更改它的人有所帮助。
Environment Variables
编辑器(文件资源管理器>右键单击此电脑>属性>高级系统设置>环境变量...)Path
变量 > 按编辑 > 放入%JAVA_HOME%bin;
在第一位置。 这是必需的,因为 Java 安装程序将C:\Program Files (x86)\Common Files\Oracle\Java\javapath
到引用最新安装的 Java 版本的PATH
中。 现在您可以使用setx
命令在 Java 版本之间切换(应在管理权限下运行):
setx /m JAVA_HOME "c:\Program Files\Java\jdk-10.0.1\
(注意:行尾没有双引号,不应该是双引号,否则你会在你的JAVA_HOME
变量中得到c:\Program Files\Java\jdk-10.0.1\"
并且它会破坏你的PATH
变量)
具有系统变量(和管理权限)的解决方案更加健壮,因为它将所需的 Java 路径放在生成的PATH
变量的开头。
如果您的路径少于 1024 个字符,则可以执行(以管理员身份运行)此脚本:
@echo off
set "JAVA5_FOLDER=C:\Java\jdk1.5.0_22"
set "JAVA6_FOLDER=C:\Java\jdk1.6.0_45"
set "JAVA7_FOLDER=C:\Java\jdk1.7.0_80"
set "JAVA8_FOLDER=C:\Java\jdk1.8.0_121"
set "JAVA9_FOLDER=C:\Java\jdk-10.0.1"
set "CLEAR_FOLDER=C:\xxxxxx"
(echo "%PATH%" & echo.) | findstr /O . | more +1 | (set /P RESULT= & call exit /B %%RESULT%%)
set /A STRLENGTH=%ERRORLEVEL%
echo path length = %STRLENGTH%
if %STRLENGTH% GTR 1024 goto byebye
echo Old Path: %PATH%
echo ===================
echo Choose new Java Version:
echo [5] JDK5
echo [6] JDK6
echo [7] JDK7
echo [8] JDK8
echo [9] JDK10
echo [x] Exit
:choice
SET /P C=[5,6,7,8,9,x]?
for %%? in (5) do if /I "%C%"=="%%?" goto JDK_L5
for %%? in (6) do if /I "%C%"=="%%?" goto JDK_L6
for %%? in (7) do if /I "%C%"=="%%?" goto JDK_L7
for %%? in (8) do if /I "%C%"=="%%?" goto JDK_L8
for %%? in (9) do if /I "%C%"=="%%?" goto JDK_L9
for %%? in (x) do if /I "%C%"=="%%?" goto byebye
goto choice
@echo on
:JDK_L5
set "NEW_PATH=%JAVA5_FOLDER%"
goto setPath
:JDK_L6
@echo off
set "NEW_PATH=%JAVA6_FOLDER%"
goto setPath
:JDK_L7
@echo off
set "NEW_PATH=%JAVA7_FOLDER%"
goto setPath
:JDK_L8
@echo off
set "NEW_PATH=%JAVA8_FOLDER%"
goto setPath
:JDK_L9
@echo off
set NEW_PATH = %JAVA9_FOLDER%
:setPath
Call Set "PATH=%%PATH:%JAVA5_FOLDER%=%CLEAR_FOLDER%%%"
Call Set "PATH=%%PATH:%JAVA6_FOLDER%=%CLEAR_FOLDER%%%"
Call Set "PATH=%%PATH:%JAVA7_FOLDER%=%CLEAR_FOLDER%%%"
Call Set "PATH=%%PATH:%JAVA8_FOLDER%=%CLEAR_FOLDER%%%"
Call Set "PATH=%%PATH:%JAVA9_FOLDER%=%CLEAR_FOLDER%%%"
rem echo Interim Path: %PATH%
Call Set "PATH=%%PATH:%CLEAR_FOLDER%=%NEW_PATH%%%"
setx PATH "%PATH%" /M
call set "JAVA_HOME=%NEW_PATH%"
setx JAVA_HOME %JAVA_HOME%
echo New Path: %PATH%
:byebye
echo
java -version
pause
如果超过 1024,请尝试删除一些不必要的路径,或者可以使用来自https://superuser.com/questions/387619/overcoming-the-1024-character-limit-with-setx的一些输入来修改此脚本
运行此 BAT 文件可以方便地更改 java 版本。
以下条目%JAVA_HOME%\bin
必须附加到PATH
环境变量中。
@echo off
@cls
@title Switch Java Version
setlocal EnableExtensions DisableDelayedExpansion
:: This bat file Switches the Java Version using the JAVA_HOME variable.
:: This script does NOT modify the PATH system environment variable.
:: Precondition: The following entry "%JAVA_HOME%\bin" has to be appended to the PATH environment variable.
:: Script Name: SwitchJavaVersion | Version 1 | 2021/11/04
rem Add items to vector as follows:
rem AvailableVersions["Java Major Version Number"]="Java Absolute Path"
set AvailableVersions[8]="D:\Program Files\Java\jdk8u252-b09"
set AvailableVersions[17]="D:\Program Files\Java\jdk-17.0.1"
call :PrintJavaVersion
call :PrintAvailableVersions
call :GetJavaVersion
call :SetJavaVersion
call :ResetLocalPath
if %errorlevel% neq 0 exit /b %errorlevel%
call :PrintJavaVersion
pause
endlocal
exit /b
rem Print available versions.
:PrintAvailableVersions
echo Available Java Versions:
for /f "tokens=2 delims=[]" %%I in ('set AvailableVersions[') do echo ^> %%I
exit /b
rem Get version from user input or command-line arguments.
:GetJavaVersion
set "JavaVersion="
if "%~1"=="" (
set /p JavaVersion="Type the major java version number you want to switch to: "
) else (
set /a JavaVersion="%~1"
)
exit /b
rem Update JAVA_HOME user variable with hardcoded paths.
:SetJavaVersion
set JavaPath=
for /f "tokens=2 delims=[]" %%I in ('set AvailableVersions[') do (
if "%%I" == "%JavaVersion%" (
setlocal EnableDelayedExpansion
set JavaPath=!AvailableVersions[%%I]!
setlocal EnableExtensions DisableDelayedExpansion
)
)
if not defined JavaPath (
echo "Specified version NOT found: Default settings applied."
for /f "tokens=2 delims==" %%I in ('set AvailableVersions[') do (
set JavaPath=%%I
goto exitForJavaPath
)
)
:exitForJavaPath
rem remove quotes from path
set JavaPath=%JavaPath:"=%
set "JAVA_HOME=%JavaPath%"
setx JAVA_HOME "%JAVA_HOME%"
rem setlocal statement was run 2 times previously inside the for loop; therefore, the endlocal statement must be executed 2 times to close those nested local scopes.
rem below endlocal statement will close local scope set by previous "setlocal EnableExtensions DisableDelayedExpansion" statement
endlocal & set "JavaPath=%JavaPath%"
rem JAVA_HOME's value rolls back due to endlocal statement so the appropriate value has to be reassigned
set "JAVA_HOME=%JavaPath%"
rem below endlocal statement will close local scope set by previous "setlocal EnableDelayedExpansion" statement
endlocal & set "JavaPath=%JavaPath%"
rem JAVA_HOME's value rolls back due to endlocal statement so the appropriate value has to be reassigned
set "JAVA_HOME=%JavaPath%"
exit /b
rem Get User and System Path variable's definition from Registry,
rem evaluate the definitions with the new values and reset
rem the local path variable so newly set java version
rem is properly displayed.
:ResetLocalPath
set "PathValue="
for /F "skip=2 tokens=1,2,*" %%I in ('%SystemRoot%\System32\reg.exe QUERY "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /V Path') do if /I "%%I" == "Path" if not "%%~K" == "" if "%%J" == "REG_SZ" (set "PathValue=%%~K") else if "%%J" == "REG_EXPAND_SZ" call set "PathValue=%%~K"
if not defined PathValue goto pathError
set "UserPathValue="
for /F "skip=2 tokens=1,2,*" %%I in ('%SystemRoot%\System32\reg.exe QUERY "HKCU\Environment" /V Path') do if /I "%%I" == "Path" if not "%%~K" == "" if "%%J" == "REG_SZ" (set "UserPathValue=%%~K") else if "%%J" == "REG_EXPAND_SZ" call set "UserPathValue=%%~K"
if not defined UserPathValue goto pathError
call set "Path=%PathValue%;%UserPathValue%"
echo Path variable reset:
echo PATH=%Path%
echo.
exit /b
rem Display the Java version.
:PrintJavaVersion
echo Current Java Version:
java -version
echo.
exit /b
rem Error handling subroutine.
:pathError
echo.
echo Error while refreshing the PATH variable:
echo PathValue=%PathValue%
echo UserPathValue=%UserPathValue%
pause
exit /b 2
endlocal
exit
在 PowerShell 开始时加载下面提到的 PowerShell 脚本。 或使用New-Item $profile -Type File -Force
生成文件,这将在此处创建一个文件C:\Users\{user_name}\Documents\WindowsPowerShell\Microsoft.PowerShell_profile
现在复制粘贴下面给出的内容在每次启动 PowerShell 时加载的文件中
将您需要的所有 java 版本设置为单独的变量。
在 power shell 中运行以将版本更新为 8 update_java_version 8 $True
要更新执行策略以允许在 PowerShell 启动时加载脚本,请使用以下命令Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Unrestricted -Force
`
function update_java_version($version, [bool] $everywhere)
{
switch ($version)
{
8 {
$java_value = (Get-Item Env:Java_8_home).value
$Env:Java_Home = $java_value
refresh-path
break
}
11 {
$java_value = (Get-Item Env:Java_11_home).value
$Env:Java_Home = $java_value
refresh-path
break
}
17 {
$java_value = (Get-Item Env:Java_17_home).value
$Env:Java_Home = $java_value
refresh-path
break
}
default {
throw "No matching java version found for `$version`: $version"
}
}
if ($everywhere)
{
[System.Environment]::SetEnvironmentVariable("Java_Home", $java_value, "User")
}
}
function refresh-path
{
$env:Path = [System.Environment]::GetEnvironmentVariable("Path", "Machine") +
";" +
[System.Environment]::GetEnvironmentVariable("Path", "User")
}
添加到此处提供的答案( https://stackoverflow.com/a/64459399/894565 )。
我通过 UI 为Java11
、 Java17
和Java8
手动创建了环境变量。 要跨 Java 版本进行更改:
从 powershell ( PJV.ps1
):
if($args[0] -eq "11") {
$Env:JAVA_HOME="$ENV:JAVA11"
$Env:Path="$Env:JAVA_HOME\bin;$Env:Path"
} elseif($args[0] -eq "17") {
$Env:JAVA_HOME="$ENV:JAVA17"
$Env:Path="$Env:JAVA_HOME\bin;$Env:Path"
} elseif($args[0] -eq "8") {
$Env:JAVA_HOME="$ENV:JAVA8"
$Env:Path="$Env:JAVA_HOME\bin;$Env:Path"
}
set "Path=%JAVA_HOME%\bin;%Path%"
java -version
从命令行( JV.bat
):
@echo off
if "%~1" == "11" (
set "JAVA_HOME=%JAVA11%"
setx JAVA_HOME "%JAVA11%"
) else if "%~1" == "17" (
set "JAVA_HOME=%JAVA17%"
setx JAVA_HOME "%JAVA17%"
) else (
set "JAVA_HOME=%JAVA8%"
setx JAVA_HOME "%JAVA8%"
)
set "Path=%JAVA_HOME%\bin;%Path%"
java -version
最后,这两个文件都在同一个文件夹中。 并且此文件夹路径已添加到我的系统PATH
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.