How to Switch Java Version on Mac

macOS includes a built-in tool, /usr/libexec/java_home, that locates any installed JDK by version number. Use it to switch the active Java version in one command.

One-time switch (current shell only)

export JAVA_HOME=$(/usr/libexec/java_home -v 17)
java -version   # confirms 17
export JAVA_HOME=$(/usr/libexec/java_home -v 21)
java -version   # confirms 21

Permanent default (add to ~/.zshrc)

echo 'export JAVA_HOME=$(/usr/libexec/java_home -v 21)' >> ~/.zshrc
source ~/.zshrc

Shell aliases for quick switching

# Add to ~/.zshrc:
alias java17='export JAVA_HOME=$(/usr/libexec/java_home -v 17) && java -version'
alias java21='export JAVA_HOME=$(/usr/libexec/java_home -v 21) && java -version'

List all installed JDKs

/usr/libexec/java_home -V

Output example:

Matching Java Virtual Machines (2):
    21.0.3 (arm64) "Eclipse Adoptium" - "OpenJDK 21.0.3" /Library/Java/JavaVirtualMachines/temurin-21.jdk/...
    17.0.11 (arm64) "Eclipse Adoptium" - "OpenJDK 17.0.11" /Library/Java/JavaVirtualMachines/temurin-17.jdk/...

jenv — per-directory switching

brew install jenv
echo 'eval "$(jenv init -)"' >> ~/.zshrc
source ~/.zshrc

# Register installed JDKs:
jenv add /Library/Java/JavaVirtualMachines/temurin-21.jdk/Contents/Home
jenv add /Library/Java/JavaVirtualMachines/temurin-17.jdk/Contents/Home

# Set global default:
jenv global 21.0

# Set per-project (creates .java-version in current directory):
cd ~/projects/my-old-project
jenv local 17.0

SDKMAN! — manages more than JDKs

curl -s "https://get.sdkman.io" | bash
source ~/.sdkman/bin/sdkman-init.sh
sdk install java 21.0.3-tem
sdk install java 17.0.11-tem
sdk default java 21.0.3-tem
sdk use java 17.0.11-tem      # switch current shell

Verify after switching

java -version
echo $JAVA_HOME