如何在macOS上设置或更改默认的Java(JDK)版本?

1332

如何在Mac上更改Java的默认版本?


4
执行/usr/libexec/java_home命令会告诉你什么? - Bart
2
/usr/libexec/java_home 返回 /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home - Venkat
也许你只需要重新启动一下。你试过了吗? - Bart
1
是的,我重启了电脑和终端……但没有改变。 - Venkat
9
您能否接受下面由@markhellewell高票获得的答案呢?这会帮助我更快地找到它,而且也很友好。 :) - Taytay
显示剩余2条评论
37个回答

2402

首先运行/usr/libexec/java_home -V,将会输出如下内容:

Matching Java Virtual Machines (3):
1.8.0_05, x86_64:   "Java SE 8" /Library/Java/JavaVirtualMachines/jdk1.8.0_05.jdk/Contents/Home
1.6.0_65-b14-462, x86_64:   "Java SE 6" /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home
1.6.0_65-b14-462, i386: "Java SE 6" /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home

/Library/Java/JavaVirtualMachines/jdk1.8.0_05.jdk/Contents/Home

选择你想要成为默认版本的版本(例如,1.6.0_65-b14-462),然后执行以下步骤:

export JAVA_HOME=`/usr/libexec/java_home -v 1.6.0_65-b14-462`

或者您可以仅指定主要版本,例如:

export JAVA_HOME=`/usr/libexec/java_home -v 1.8`

现在当您运行java -version时,您将看到:

java version "1.6.0_65"
Java(TM) SE Runtime Environment (build 1.6.0_65-b14-462-11M4609)
Java HotSpot(TM) 64-Bit Server VM (build 20.65-b04-462, mixed mode)
export JAVA_HOME...行添加到您的shell的init文件中。 对于Bash(由antonyh指定):
export JAVA_HOME=$(/usr/libexec/java_home -v 1.8)
< p >对于鱼(如ormurin所述)< /p >
set -x JAVA_HOME (/usr/libexec/java_home -d64 -v1.8)

更新 .zshrc 文件应该可以解决:

nano ~/.zshrc

export JAVA_HOME=$(/usr/libexec/java_home -v 1.8.0)

按下CTRL+X退出编辑器 按Y保存更改

source ~/.zshrc
echo $JAVA_HOME
java -version

18
确实是反引号符,export 行。 - David West
11
这对我没用。从运行java_home -V获取路径,并将其添加到export命令中,就像这样:export JAVA_HOME="/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home"。 - oden
83
在Bash中,这个命令可以正常工作 - export JAVA_HOME=$(/usr/libexec/java_home -v 1.8) - 还要注意的是,java_home命令允许部分匹配,因此您不需要包含完整版本号,它会自动查找最新安装的版本。这样可以更轻松地更新。 - antonyh
21
确保导出时使用的是 而非 ' '。 - blizzard
10
我希望每次我需要在Google上搜索“OS X切换Java版本”并返回到这里时,都能够点赞这篇文章。 - Raibaz
显示剩余23条评论

580

这篇回答旨在解决以下问题:如何在macOS El Capitan或更新版本(Sierra,High Sierra,Mojave)上安装多个JDK用于开发目的时,全局控制Java版本(不仅限于当前运行的shell)。据我所知,目前没有任何一个回答可以做到这一点。

作为开发人员,我使用多个JDK,并且希望能够轻松地切换。通常,我会有一个最新的稳定版本供一般使用,以及其他版本供测试使用。但是,我不希望系统(例如当我启动我的IDE时)使用我现在拥有的最新的“早期访问”版本。我想要控制系统的默认版本,应该是最新的稳定版本。

以下方法适用于至少Java 7到12(截至本文撰写时),包括Oracle JDKOpenJDK(包括AdoptOpenJDK在2018年10月中旬之后发布的版本)。

无需第三方工具的解决方案:

  • 将所有JDK保留在默认位置/Library/Java/JavaVirtualMachines下。系统会默认选择最高版本。
  • 如果想要排除某个JDK被系统默认选择,将其Contents/Info.plist重命名为Info.plist.disabled。当$JAVA_HOME指向该JDK或在脚本或配置中明确引用时,仍然可以使用该JDK。但是,系统的java命令将忽略它。

系统启动器将使用具有Info.plist文件的最高版本的JDK。

在使用备选JDK的shell中工作时,可以从现有答案(jenv或围绕/usr/libexec/java_home的自定义别名/脚本)中选择方法。


调查细节在这个代码片段中


(*) 当前的答案要么已经过时(不能用在macOS El Capitan或Sierra上),要么只适用于单个JDK,要么不涉及系统范围。许多解释如何更改$JAVA_HOME,但这只影响当前shell和从那里启动的内容。它不会影响从OS launcher启动的应用程序(除非您更改正确的文件并注销/登录,这很繁琐)。对于jenv而言,虽然它很酷,但据我所知,它仅更改环境变量,因此具有相同的限制。


22
这就是我一直在寻找的答案,因为 jenvJAVA_HOME 都不能设置系统范围内的 Java 版本,也就是 Eclipse 将要使用的版本。 - Giovanni Lovato
4
是的,正如“调查详情”所述(上面有链接):“安装JDK还会覆盖/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/。显然,这就是新首选项窗格将启动的插件——这是我发现解决方案唯一的例外:那个插件仍将使用JDK9(我安装的最新版本),但没有其他Java应用程序会这样做。” - Hugues M.
3
值得注意的是,Java版本可以在/Library/Java/JavaVirtualMachines目录中找到,并且上述出色的工作解决方案就在这个上下文中。 - Andrew Kostka
4
没错,这是针对这个问题最好、最实用的解决方案。可惜如此。 - Aerodynamika
4
非常感谢您的答复,这解决了从操作系统启动器启动应用程序的问题。 - Karthic Raghupathi
显示剩余14条评论

412

除了以上的答案,我在我的.bash_profile(或者对于MacOS 10.15+的.zshrc)中添加了以下几行代码,这使得切换变得非常方便(包括@elektromin关于java 9的评论):

alias j20="export JAVA_HOME=`/usr/libexec/java_home -v 20`; java -version"
alias j19="export JAVA_HOME=`/usr/libexec/java_home -v 19`; java -version"
alias j18="export JAVA_HOME=`/usr/libexec/java_home -v 18`; java -version"
alias j17="export JAVA_HOME=`/usr/libexec/java_home -v 17`; java -version"
alias j16="export JAVA_HOME=`/usr/libexec/java_home -v 16`; java -version"
alias j15="export JAVA_HOME=`/usr/libexec/java_home -v 15`; java -version"
alias j14="export JAVA_HOME=`/usr/libexec/java_home -v 14`; java -version"
alias j13="export JAVA_HOME=`/usr/libexec/java_home -v 13`; java -version"
alias j12="export JAVA_HOME=`/usr/libexec/java_home -v 12`; java -version"
alias j11="export JAVA_HOME=`/usr/libexec/java_home -v 11`; java -version"
alias j10="export JAVA_HOME=`/usr/libexec/java_home -v 10`; java -version"
alias j9="export JAVA_HOME=`/usr/libexec/java_home -v 9`; java -version"
alias j8="export JAVA_HOME=`/usr/libexec/java_home -v 1.8`; java -version"
alias j7="export JAVA_HOME=`/usr/libexec/java_home -v 1.7`; java -version"

插入后,执行$ source .bash_profile

我可以通过输入以下内容切换到Java 8:

$ j8
java version "1.8.0_102"
Java(TM) SE Runtime Environment (build 1.8.0_102-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.102-b14, mixed mode)

7
这是Java 9的语法:alias j9="export JAVA_HOME=`/usr/libexec/java_home -v 9`; java -version" 该语法用于创建一个名为“j9”的别名,它将设置JAVA_HOME变量以指向Java 9,并输出Java版本信息。 - elektromin
4
快速切换的简单别名,非常棒。 - gbonetti
我会制作一个类似于 nvm 的命令行工具来切换 Java 版本,但是首字母缩写 jvm 已经有了其他的意思 :) - Andy
当我进行资源引用时,出现了以下错误:/Users/me/.zshrc:8: permission denied: /Library/Java/JavaVirtualMachines/openjdk-12.jdk/Contents/Home - cosbor11
这真是太聪明了!帮了大忙! - undefined
显示剩余5条评论

65
基于 /usr/libexec/java_home 的小鱼函数。
function jhome
    set JAVA_HOME (/usr/libexec/java_home $argv)
    echo "JAVA_HOME:" $JAVA_HOME
    echo "java -version:"
    java -version
end

如果您不使用 fish,您可以在 bash 中执行类似的操作:

#!/bin/bash

jhome () {
  export JAVA_HOME=`/usr/libexec/java_home $@`
  echo "JAVA_HOME:" $JAVA_HOME
  echo "java -version:"
  java -version
}

切换 Java 版本请执行以下命令:

$> jhome           #switches to latest java
$> jhome -v 1.7    #switches to java 1.7
$> jhome -v 1.6    #switches to java 1.6

参考:https://gist.github.com/kenglxn/1843d552dff4d4233271


2
这仅更改特定终端会话。有没有一种方法可以更新它以在整个系统范围内更改? - ENG618
1
我不得不写export JAVA_HOME=(/usr/libexec/java_home $argv)代替你的jhome函数的第二行。 - Daniel A.A. Pelsmaeker

61
由于多个Homebrew、cast(Deprecation Notice AdoptOpenJDK/openjdk)和MacOS的更新,我发布了这个更新的答案。
Homebrew tap AdoptOpenJDK/openjdk已正式弃用,取而代之的是直接从Homebrew项目提供的temurin casks,但Homebrew是管理和使用不同Java版本的最佳方式。
如果您已经安装了Homebrew和AdoptOpenJDK/openjdk cast,请先取消此brew tap。
$ brew untap AdoptOpenJDK/openjdk

如果你没有安装Homebrew。
1 - 安装Homebrew。
$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

2 - 下载最新的Java版本(16):
$ brew install --cask temurin

3 - 安装其他版本:
$ brew tap homebrew/cask-versions
$ brew install --cask temurin8
$ brew install --cask temurin11
$ brew install --cask temurin17
$ brew install --cask temurin18
$ brew install --cask temurin19
$ brew install --cask temurin21

4 - 切换不同版本的Java

要在不同版本的Java之间切换,只需将以下内容添加到您的.bash_profile.zshrc文件中。

在这种情况下,我们希望能够在Java8、Java11、Java17和Java21之间进行切换:

export JAVA_8_HOME=$(/usr/libexec/java_home -v1.8)
export JAVA_11_HOME=$(/usr/libexec/java_home -v11)
export JAVA_17_HOME=$(/usr/libexec/java_home -v17)
export JAVA_18_HOME=$(/usr/libexec/java_home -v18)
export JAVA_19_HOME=$(/usr/libexec/java_home -v19)
export JAVA_21_HOME=$(/usr/libexec/java_home -v21)

alias java8='export JAVA_HOME=$JAVA_8_HOME'
alias java11='export JAVA_HOME=$JAVA_11_HOME'
alias java17='export JAVA_HOME=$JAVA_17_HOME'
alias java18='export JAVA_HOME=$JAVA_18_HOME'
alias java19='export JAVA_HOME=$JAVA_19_HOME'
alias java21='export JAVA_HOME=$JAVA_21_HOME'

# default to Java 21
java21

5 - 重新加载 .bash_profile.zshrc 以使别名生效:
$ source ~/.bash_profile

或者

$ source ~/.zshrc

6 - 最后,您可以使用别名在不同的Java版本之间切换。
$ java8
$ java -version
java version "1.8.0_261"

老司机,如果你使用的是旧版Homebrew和MacOS版本...
我将分享一下我在macOS Big Sur v11.4上的经验,解决这些问题的最佳方法是使用Homebrew安装Java:
1 - 安装Homebrew。
$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

2 - 安装Homebrew Cask。
$ brew tap homebrew/cask-versions 
$ brew update 
$ brew tap homebrew/cask

3 - 安装最新版本的Java
$ brew cask install java

4 - 安装其他所需的Java版本(Java8、Java11、Java13)。
$ brew tap adoptopenjdk/openjdk

$ brew cask install adoptopenjdk8
$ brew cask install adoptopenjdk11
$ brew cask install adoptopenjdk13
$ brew cask install adoptopenjdk14

5 - 切换不同版本的Java

要在不同版本的Java之间切换,您只需要将以下内容添加到您的.bash_profile.zshrc文件中。

在这种情况下,我们希望能够在Java8、Java11、Java13和Java14之间进行切换:

export JAVA_8_HOME=$(/usr/libexec/java_home -v1.8)
export JAVA_11_HOME=$(/usr/libexec/java_home -v11)
export JAVA_13_HOME=$(/usr/libexec/java_home -v13)
export JAVA_14_HOME=$(/usr/libexec/java_home -v14)

alias java8='export JAVA_HOME=$JAVA_8_HOME'
alias java11='export JAVA_HOME=$JAVA_11_HOME'
alias java13='export JAVA_HOME=$JAVA_13_HOME'
alias java14='export JAVA_HOME=$JAVA_14_HOME'

# default to Java 14
java14

6 - 重新加载 .bash_profile.zshrc 以使别名生效:
$ source ~/.bash_profile

或者

$ source ~/.zshrc

7 - 最后,您可以使用别名在不同的Java版本之间进行切换。
$ java8
$ java -version
java version "1.8.0_261"

更多信息,请参阅此帖子:如何使用Brew在Mac上安装Java

@hermeslm,能否帮忙做个小修改?看到这个:brew tap caskroom/cask Error: caskroom/cask was moved. Tap homebrew/cask instead. - hafichuk
很好的发现@hafichuk,在我回答时它有效。我会编辑它,谢谢。 - hermeslm
@hermeslm brew cask install 无法使用于新版本,需更新为: brew install cask packageName。参考链接:https://dev59.com/Ql0a5IYBdhLWcg3wYXq8 - Shivam Sahil
我不得不运行 brew install adoptopenjdk/openjdk/adoptopenjdk8 而不是 brew cask install adoptopenjdk8 - Vlad R
2022年11月Mac更新:`export JAVA_11_HOME=/opt/homebrew/Cellar/openjdk@11/11.0.16.1/libexec/openjdk.jdk/Contents/Home export JAVA_17_HOME=/opt/homebrew/Cellar/openjdk@17/17.0.4.1/libexec/openjdk.jdk/Contents/Home export JAVA_18_HOME=/opt/homebrew/Cellar/openjdk/18.0.2.1/libexec/openjdk.jdk/Contents/Homealias java11='export JAVA_HOME=$JAVA_11_HOME' alias java17='export JAVA_HOME=$JAVA_17_HOME' alias java18='export JAVA_HOME=$JAVA_18_HOME'

默认使用Java 14

java18`
- lkahtz
对于那些想要一些反馈的人,可以使用以下命令:alias java17='export JAVA_HOME=$JAVA_17_HOME && echo JAVA_HOME set to $JAVA_HOME' - Bjørnar Hvidsten

53

使用jenv是一种简单的方式。(更新于2022年)

  1. 安装jenv:请参见入门指南

  2. 使用brew安装Java

brew install openjdk@11
ln -s /usr/local/opt/openjdk@11/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk-11.jdk

#other java
brew install openjdk@8
brew install openjdk@17
  • 将Java添加到jenv中

  • jenv add /Library/Java/JavaVirtualMachines/openjdk-11.jdk/Contents/Home
    
  • 使用:参考jenv


  • 干净漂亮的解决方案。 - pinturic
    我需要使用“jenv shell 1.8”而不是“jenv use java 1.8”。根据需要,“shell”也可以是“global”或“local”。 - Steve Gelman
    3
    jenv在使用时很好。但是我不建议使用它,因为它并没有“真正”更改默认的Java版本,这一点可以通过运行命令“/usr/libexec/java_home -V”来证实,它只更改了JAVA_HOME。这会导致一些应用程序出现奇怪的问题,比如Eclipse。 - simon
    1
    除此之外,我内心的偏执狂建议不要将任何东西都传输到bash。即使你认为这个网站是可信的,也没有人能保证它是无法被黑客攻击的。请使用您操作系统的软件包管理器。 - Aleksandr Kravets
    那个信息已经过时了。请查看官方文档或者更详细的说明 - fabianopinto
    现在配置jenv的方法已经有所不同了。请参考此链接:https://www.jenv.be/ - Munim

    42

    安装JDK,而不仅仅是JRE

    /usr/libexec/java_home -v 1.8
    

    提供

    /Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home
    

    下一个

    touch .bash_profile
    
    open -a TextEdit.app .bash_profile
    

    TextEdit将显示一个空白页面,您可以填写。

    添加到文档中: export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home

    在终端中:

    export JAVA_HOME="$(/usr/libexec/java_home -v 1.8)"
    

    尝试执行以下命令:

    javac -version

    应该会输出:

    javac 1.8.0_111
    

    点赞表示展示如何安装JDK。 - Calvin Taylor

    41

    虽然有点棘手,但请尝试按照在OS X 10.9(Mavericks)上安装Java所描述的步骤进行操作。基本上,你需要将别名更新为java

    具体步骤如下:

    安装JDK 1.7后,您需要执行sudo ln -snf以更改链接到当前的java。为此,请打开终端并输入以下命令:

    sudo ln -nsf /Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents \
    /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK
    

    请注意,目录jdk1.7.0_51.jdk可能会根据您安装的SDK版本而更改。

    现在,您需要设置JAVA_HOME以指向安装了jdk_1.7.0_xx.jdk的位置。再次打开终端并输入:

    export JAVA_HOME="/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home"
    

    你可以在你的.bashrc文件中添加export JAVA_HOME行,以便永久地在终端中使用Java。


    1
    如何设置JAVA_HOME变量?我需要在特定的位置设置吗? - Venkat
    我应该在哪里设置JAVA_HOME环境变量?它将被保存在哪里? - Venkat
    1
    我已经更新了答案。你知道你安装的SDK版本吗?文件夹名称采用SDK版本号,因此上面的命令可能会有所改变。 - Trein
    变量JAVA_HOME将在当前终端会话中被导出。如果您希望,可以将其添加到我们的.bashrc文件中。我将根据最新版本适配命令。 - Trein
    @Trein 我建议你不要使用你的hack,而是使用我的版本。它减少了错误的可能性,实现起来也更容易。它还能让人们同时使用1.6和1.7而不会破坏任何一个版本。 - Nikolas Grottendieck
    显示剩余5条评论

    34

    简述:在文件 ~/.bash_profile 中添加以下行:

    export JAVA_HOME='/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home'

    (将 jdk1.8.0_144.jdk 替换为您下载的版本)

    然后运行命令 source ~/.bash_profile


    31

    使用jenv,它就像是一个Java环境管理器。它非常容易使用和干净。

    对于Mac用户,按照以下步骤:

    brew install jenv
    
    git clone https://github.com/gcuisinier/jenv.git ~/.jenv
    

    安装:如果您正在使用bash,请按照以下步骤操作:

    $ echo 'export PATH="$HOME/.jenv/bin:$PATH"' >> ~/.bash_profile
    
    echo 'eval "$(jenv init -)"' >> ~/.bash_profile
    
    $ exec $SHELL -l
    

    将所需的JVM版本添加到jenv中:

    jenv add /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home
    
    jenv add /System/Library/Java/JavaVirtualMachines/1.8.0.jdk/Contents/Home
    

    检查已安装的版本:

    jenv versions
    

    通过以下方式设置您想要使用的Java版本:

    jenv global oracle64-1.6.0
    

    我正在使用类似的工具:https://sdkman.io/usage - 在我看来,这比手动别名等方法要好得多。 - SathOkh

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接