问题背景:
需要同时使用不同版本的JDK进行开发和运行,可通过下述操作改变JDK版本。
一、java分类以及JDK、JRE、JVM的联系
1、JAVA分类
JAVA EE——Java Enterprise Edition, JAVA企业版,主要用于WEB开发。
JAVA SE——Java Standard Edition, JAVA标准版,主要用于应用程序开发。
JAVA ME——Java Micro Edition, JAVA移动版(微型版),主要用于移动设备、嵌入式设备上的java应用程序开发。
2、JDK、JRE、JVM的区别
2.1.JDK
JDK是Java开发工具包,是Sun Microsystems针对Java开发员的产品。
JDK中包含JRE,在JDK的安装目录下有一个名为jre的目录,里面有两个文件夹bin和lib,在这里可以认为bin里的就是jvm,lib中则是jvm工作所需要的类库,而jvm和 lib和起来就称为jre。
JDK是整个JAVA的核心,包括了Java运行环境JRE(Java Runtime Envirnment)、一堆Java工具(javac/java/jdb等)和Java基础的类库(即Java API 包括rt.jar)。
①SE(J2SE),standard edition,标准版,是我们通常用的一个版本,从JDK 5.0开始,改名为Java SE。
②EE(J2EE),enterprise edition,企业版,使用这种JDK开发J2EE应用程序,从JDK 5.0开始,改名为Java EE。
③ME(J2ME),micro edition,主要用于移动设备、嵌入式设备上的java应用程序,从JDK 5.0开始,改名为Java ME。
2.2.JRE
是运行基于Java语言编写的程序所不可缺少的运行环境。也是通过它,Java的开发者才得以将自己开发的程序发布到用户手中,让用户使用。
JRE中包含了Java virtual machine(JVM),runtime class libraries和Java application launcher,这些是运行Java程序的必要组件。
与大家熟知的JDK不同,JRE是Java运行环境,并不是一个开发环境,所以没有包含任何开发工具(如编译器和调试器),只是针对于使用Java程序的用户。
2.3.JVM
是我们常说的java虚拟机,它是整个java实现跨平台的最核心的部分,所有的java程序会首先被编译为.class的类文件,这种类文件可以在虚拟机上执行。
也就是说class并不直接与机器的操作系统相对应,而是经过虚拟机间接与操作系统交互,由虚拟机将程序解释给本地系统执行。
只有JVM还不能成class的执行,因为在解释class的时候JVM需要调用解释所需要的类库lib,而jre包含lib类库。
JVM屏蔽了与具体操作系统平台相关的信息,使得Java程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。
2.4.三者的关系
简单来说就是JDK包含JRE,JRE又包含JVM的关系
二、JDK各版本特性总结以及下载链接
1、JDK各版本官方下载地址(官方下载需要Oracle账号[免费])
Java Archive | Oracle
版本 | 名称 | 发行日期 |
JDK 1.1.4 | Sparkler(宝石) | 1997-09-12 |
JDK 1.1.5 | Pumpkin(南瓜) | 1997-12-13 |
JDK 1.1.6 | Abigail(阿比盖尔–女子名) | 1998-04-24 |
JDK 1.1.7 | Brutus(布鲁图–古罗马政治家和将军) | 1998-09-28 |
JDK 1.1.8 | Chelsea(切尔西–城市名) | 1999-04-08 |
J2SE 1.2 | Playground(运动场) | 1998-12-04 |
J2SE 1.2.1 | none(无) | 1999-03-30 |
J2SE 1.2.2 | Cricket(蟋蟀) | 1999-07-08 |
J2SE 1.3 | Kestrel(美洲红隼) | 2000-05-08 |
J2SE 1.3.1 | Ladybird(瓢虫) | 2001-05-17 |
J2SE 1.4.0 | Merlin(灰背隼) | 2002-02-13 |
J2SE 1.4.1 | grasshopper(蚱蜢) | 2002-09-16 |
J2SE 1.4.2 | Mantis(螳螂) | 2003-06-26 |
J2SE 5.0 | 2004-09 | |
Java SE 5.0 (1.5.0) | Tiger(老虎) | 2004-09-30 |
Java SE 6.0 (1.6.0) | Mustang(野马) | 2006-04 |
Java SE 7.0 (1.7.0) | Dolphin(海豚) | 2011-07-28 |
Java SE 8.0 (1.8.0) (LST) | Spider(蜘蛛) | 2014-03-18 |
Java SE 9 | 2017-09-21 | |
Java SE 10 | 2018-03-14 | |
Java SE 11 (LST) | 2018-09-26 | |
Java SE 12 | 2019-03-20 | |
Java SE 13 | 2019-09-17 | |
Java SE 14 | 2020-03-17 | |
Java SE 15 | 2020-09 | |
Java SE 16 | 2021-03 | |
Java SE 17 (LST) | 2021-09 | |
Java SE 18 | 2022-03-22 | |
Java SE 19 | 2022-09-20 | |
Java SE 20 | 2023-03 | |
Java SE 21 | 2023-09 | |
Java SE 22 | 2024-03 |
2、JDK各版本特性总结参考链接
JDK各版本特性总结-CSDN博客
三、Windows使用JEnv实现JDK多版本管理
1、分别安装多个版本的JDK
根据实际情况选择不同版本的JDK进行安装。
我选择安装JDK8、JDK11、JDK17。
1.1.下载各版本JDK
官方下载地址(官方下载需要Oracle账号[免费]): Java Archive | Oracle
下载下述版本的内容
1.2.安装JDK8
具体安装步骤可以参考: java 8安装教程_java8安装-CSDN博客
1.3.安装JDK11、JDK17
找到JDK8的安装目录,将JDK11、JDK17压缩包解压到此文件夹下。
解压后的内容如下
2、JEnv下载、安装和常用命令
JEnv是一个帮助我们管理多个JDK安装的工具,并将每个代码库配置为使用特定的JDK版本,而不必改变JAVA_HOME环境变量.
2.1.下载JEnv
下载链接: https://github.com/FelixSelter/JEnv-for-Windows/releases
2.2.安装JEnv
将下载好的JEnv文件解压到上述jdk各版本文件夹下,解压后的内容如下(JEnv是一个自定义的文件夹,里面是JEnv文件解压后的内容)
2.3.将JEnv中jenv.bat所在路径放于系统环境变量path中
右击“此电脑”,然后选择“属性”,再点击“高级系统设置”,再点击 “环境变量”,如下图:
找到Path,选中,再点击“编辑”
然后点击“新建”,把JEnv中jenv.bat所在路径放入到这里后点击"确定"
在dos窗口中,输入jenv检测是否添加JEnv成功
2.4.JEnv命令
若执行命令时出现下图内容,需要新增一个名为JAVA_HOME的环境变量,值可以任意填一个jdk的目录,到bin上一级即可(如: C:\Program Files\Java\jdk-1.8)
在dos窗口中,可以查询当前使用的jdk版本。
java -version
2.4.1.添加JDK版本和路径(若路径中含空格,需要用英文引号括起来)
jenv add <name> <java_Path>
如:jenv add jdk8 "C:\Program Files\Java\jdk-1.8"
2.4.2.查看已添加的JDK版本
jenv list
2.4.3.切换JDK版本
jenv change <name>
如:jenv change java8
2.4.4.从 JEnv 列表中删除现有 JDK
jenv remove <name>
示例:jenv remove java8
2.5.JEnv命令实例
2.5.1.jenv add和jenv list
2.5.2.jenv list、jenv change和java -version
四、用代码的方式验证JDK版本切换是否成功
参考 java 8安装教程_java8安装-CSDN博客 中编译运行代码的内容验证JDK版本切换是否成功。
代码内容如下:
public class demo { // 声明一个名为demo的公共类
public static void main(String []args){ // 这是程序的主入口点。当Java应用程序运行时,它是首先执行的
String jdkVersion = System.getProperty("java.version"); // 使用System.getProperty方法获取系统属性"java.version",它表示当前正在运行的JDK版本,并将其存储在字符串变量jdkVersion中
System.out.println("当前JDK版本为:" + jdkVersion); // 打印一条消息,显示当前正在运行的JDK版本
} // 结束主方法
} // 结束demo类
编译运行截图如下:
注意:
执行代码时,若出现java MainDemo执行main方法报错
Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.UnsupportedClassVersionError: MainDemo has been compiled by a more recent version of the Java Runtime (class file version 61.0), this version of the Java Runtime only recognizes class file versions up to 52.0
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access$100(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.launcher.LauncherHelper.checkAndLoadMain(Unknown Source)
问题在于用低版本的jdk编译的class文件,然后在高版本的JVM上运行所导致的,即编译运行版本不匹配。因此可以在新的dos窗口中用javac demo.java编译,再运行。