
正文
java代码的jdk版本 jdk的版本都有哪些
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
大学的java是jdk8还是13
大多数大学的java课程会使用JDK8,但也有部分大学使用JDK13。建议您联系老师或查阅相关课程的教材,了解更多信息。
相关问答
Q1: java的JDK更新到什么版本了?
Standard Edition(标准版)的最新版:jdk 14。
Early-Access(先行版)的最新版:jdk15。
LTS(长期支持版)的最新版:jdk 11.0.6。
JRE(Java Runtime Environmentjava代码的jdk版本,Java运行时环境),包含了java虚拟机、java基础类库。是使用java语言编写的程序运行所需要的软件环境。
它相当于操作系统部分,提供了Java程序运行时所需要的基本条件和许多Java基础类,例如,IO类、GUI控件类、网络类等。JRE是提供给普通用户使用的,如果java代码的jdk版本你只想运行别人开发好的Java程序,那么,你的计算机上必须且只需安装JRE。
JDK(Java Development Kit,Java开发工具包),它包含编译工具、解释工具、文档制作工具、打包工具多种与开发相关的工具,是提供给Java开发人员使用的。JDK包含了JRE,同时还包含了编译java源码的编译器javac,还包含了很多java程序调试和分析的工具:jconsole,jvisualvm等工具软件,还包含了java程序编写所需的文档和demo例子程序。
Q2: Java方面JDK各版本的区别
一、java的版本区别
常用的 java 程序分为 Java SE、Java EE、Java ME三个版本,介绍如下:
1. Java SE(Java Platform,Standard Edition)
Java SE 以前称为J2SE。它允许开发和部署在桌面、服务器、嵌入式环境和实时环境中使用的 Java 应用程序。Java SE是基础包,但是也包含了支持 Java Web 服务开发的类,并为 Java Platform,Enterprise Edition(Java EE)提供基础。
2. Java EE(Java Platform,Enterprise Edition)。
这个版本以前称为 J2EE。企业版本帮助开发和部署可移植、健壮、可伸缩且安全的服务器端 Java 应用程序。Java EE 是在 Java SE 的基础上构建的,它提供 Web 服务、组件模型、管理和通信 API,可以用来实现企业级的面向服务体系结构(service-oriented architecture,SOA)和 Web 2.0 应用程序。
3. Java ME(Java Platform,Micro Edition)。
这个版本以前称为 J2ME。Java ME 为在移动设备和嵌入式设备(比如手机、PDA、电视机顶盒和打印机)上运行的应用程序提供一个健壮且灵活的环境。Java ME 包括灵活的用户界面、健壮的安全模型、许多内置的网络协议以及对可以动态下载的连网和离线应用程序的丰富支持。基于 Java ME 规范的应用程序只需编写一次,就可以用于许多设备,而且可以利用每个设备的本机功能。
说得更简单片面一点:
Java SE 是做电脑上运行的软件。
Java EE 是用来做网站的-(我们常见的JSP技术)
Java ME 是做手机软件的。
二、学习JAVA从哪开始?
或者我们可以说,需要先学习那个java版本?
有道是“万丈高楼平地起”,通过上面的介绍我们就可以知道,学习java编程,无论想从事哪个方面的程序开发,必须要把基础打好,因此,学习java应该从 java se开始学习。
Q3: JAVA的JDK最新版本是多少?
JDK当前的最新版本是JDK14。
从JDK9之后,Java每隔半年发布一次版本,版本发布历史为:
JDK10,发布时间2018.03.20
JDK11,发布时间2018.09.25
JDK12,发布时间2019.03.19
JDK13,发布时间2019.09.17
JDK14,发布时间2020.03.17
JDK15,目前正处于开发中
Q4: java选的jdk11为什么变成了17
Java11升级Java17备忘录

下塘烧饼
白头不厌穷编码,只影孤灯两卷书。
来自专栏一只老程序猿
一、概述
Java17是目前Java最新的LTS版本,SpringBoot从2.5.5开始正式支持Java17,并且计划从3.0版本开始,Java版本要求最低是Java17。
为了顺应Java及其生态的发展,最近对一套JavaWeb开发框架做了版本升级,主要是Java版本和Springboot版本的升级,包括:
Java版本从openJDK11升级到openJDK17
springboot版本从2.1.11升级到2.7.4
本次升级相比从Java8升级到Java11要简单很多,基本没遇到什么问题。
Java8到Java11之间有Java9这个变化很大的拦路虎,包括但不限于:移除了一些以前集成在jdk的lib中的依赖包,引入模块化导致某些内部API不可用,类加载机制变化导致一些第三方依赖包版本不兼容,等等。
而从Java11到Java17,中间并没有Java9那样巨大的变化,只有Java16和Java17中有一些增强Java内部封装的新特性,可能会导致底层类库依赖包的老版本不能兼容Java17。
关于Java8升级Java11的工作,可以参考我以前的文章:
java - Java8升级Java11备忘录_个人文章 - SegmentFault 思否
另外,本篇文章主要讲如何从Java11升级到Java17,以及升级过程中遇到的一些问题。如果想看Java11到Java17有哪些新特性,可以参考我以前的另一片文章:
下塘烧饼:java17相对java11的新特性
二、升级工作内容
升级工作内容大致如下:
2.1 安装openJDK17及其对应的IDEA
这里选择的是eclipse的Adoptium社区版本:
OpenJDK17U-jdk_x64_linux_hotspot_17.0.3_7.tar.gz
下载地址:
更多版本与下载地址请参考文章:
下塘烧饼:java17相对java11的新特性
安装很简单,解压缩到指定目录即可。
只是开发的话,JAVA_HOME与PATH等环境变量不是一定要设置的,比如我这里的环境有多个JDK版本,只要在IDE中添加新的JDK即可。
IDEA的话,使用2021.2.4以上版本即可支持Java17,在其sdk中加入刚刚安装好的JDK目录:
用IDEA任意打开一个java工程,在其Project Structrue - Platform settings - SDKs中添加JDK17目录。
2.2 配置本地Maven
在本地Maven的配置文件中添加新的JDK17的profile,比如我这里的配置文件是/opt/apache-maven-3.5.0/conf/settings.xml,打开并在其中添加:
profiles ... profile idopenJDK17/id activation jdk17/jdk /activation properties JAVA_HOME/usr/java/jdk-17.0.3+7//JAVA_HOME JAVA_VERSION17/JAVA_VERSION maven.compiler.source17/maven.compiler.source maven.compiler.target17/maven.compiler.target maven.compiler.compilerVersion17/maven.compiler.compilerVersion /properties repositories repository idXXX-Repository/id nameXXX Maven Repository/name url;/url snapshots enabledtrue/enabled /snapshots /repository /repositories pluginRepositories pluginRepository idXXX-Repository/id nameXXX Maven Repository/name url;/url snapshots enabledtrue/enabled /snapshots /pluginRepository /pluginRepositories /profile /profiles
JAVA_HOME是本地JDK安装目录。
repository与pluginRepository用来配置maven仓库地址,之后在IDE中启用这里配置的profile。这样maven拉取jar包时,会优先从这里配置的maven仓库拉取,拉取不到时再去中央仓库拉。
配置好settings.xml后,在各个java工程中启用新的profile:
首先在File - Settings - Maven中确定maven及其配置文件目录:
然后在IDEA的maven插件中选择jdk17的profile:
2.3 修改父工程的pom版本控制
升级对象是一套JavaWeb开发框架,有自己的父工程来控制依赖包的版本,在决定升级Java版本与Springboot版本后,父工程的pom文件中的相关依赖包版本需要更新。
首先是父工程自己的版本需要升级,这样仍然依赖老版本父工程的java工程就不会升级相关版本,只有依赖了新版本父工程的java工程才会升级相关版本。
artifactIdparent-xxx/artifactId version2.0.0/version
这里假定老版本是1.x.x,新版本是2.0.0。
实际上父工程的pom是在升级过程中不断修改的,为了不影响使用该父工程的项目开发,你需要与相关开发人员约定好在升级完成后再尝试使用新版本的父工程。
然后修改基本属性与spring相关依赖包的版本,篇幅原因这里只给出版本发生变化的依赖包的修改后版本号,dependency配置略过:
properties !-- 基本属性 -- project.build.sourceEncodingUTF-8/project.build.sourceEncoding project.reporting.outputEncodingUTF-8/project.reporting.outputEncoding java.version17/java.version !-- spring相关版本 -- spring-boot.version2.7.4/spring-boot.version spring-boot-admin.version2.7.4/spring-boot-admin.version spring-cloud.version2021.0.4/spring-cloud.version spring-cloud-alibaba.version2021.0.1.0/spring-cloud-alibaba.version mybatis-spring-boot-starter.version2.2.2/mybatis-spring-boot-starter.version pagehelper-spring-boot-starter.version1.4.5/pagehelper-spring-boot-starter.version !-- 插件版本 -- spring-boot-maven-plugin.version2.7.4/spring-boot-maven-plugin.version mybatis-generator-maven-plugin.version1.4.1/mybatis-generator-maven-plugin.version !-- 其他依赖包版本 -- lombok.version1.18.24/lombok.version /properties
升级后的测试并不充分,这里列出的发生版本变化的依赖包可能并不全面。
如果在编译或运行时发现有某个依赖包报错,说某个jdk的module因为没有导出而无法访问的错误: cannot access class xxx (in module jdk.xxx) because module jdk.xxx does not export xxx to xxx,那么就基本可以确定这个依赖包版本较老不兼容Java17。
解决方法很简单,在当前这个时间点,基本上所有的第三方依赖包都已经有兼容Java17的较新的版本,直接去maven中央仓库找一个新版本下载,就能解决问题。
比如上面的lombok版本升级到了1.18.24,就是为了解决编译时发生的上述不兼容的错误。
另外,如果父工程中还约定了很多自用的通用工程的版本,那么这里需要确保这些通用工程的版本范围在新老版本中的定义没有冲突。
例如老版本的父工程中定义了一些通用工程的版本:
lib-xxx.version[1.0.0-RELEASE,2.0.0-RELEASE)/lib-xxx.version
这里的lib-xxx是这套JavaWeb开发框架中的一个通用库,在老版本的父工程中约定它的版本范围是[1.0.0-RELEASE,2.0.0-RELEASE),即从1.0.0-RELEASE(包含)到2.0.0-RELEASE(不包含)。那么新版本的父工程,对它的版本范围约定就是[2.0.0-RELEASE,3.0.0-RELEASE)。
这样约定的目的是,如果有一些java工程仍然要使用老版本的父工程(假定由于种种原因,只能用Java11与Springboot2.1.x 。。。),那么它就不会依赖2.0.0-RELEASE及其以上版本的lib-xxx;而一旦依赖了新版本的父工程,就只会依赖2.0.0-RELEASE及其以上版本的lib-xxx。
最后要注意,如果在老版本(这里就是Java11和Springboot2.1.11)上还有新的应用或需求变更要开发,那么需要在代码管理库中切出一个新的分支来做升级的工作,并约定好各自的版本范围,比如采用不同的主版本号。
2.4 单个Java工程的版本升级
在前面的2.1到2.3准备工作完成之后,就可以对java应用工程做版本升级了。
首先打开一个java工程,确认maven的目录与配置文件是否正确,并将maven插件的profile选择到jdk17,这一步已在步骤2.2中示意。
然后修改工程依赖的父工程版本为2.3中修改后的父工程版本。
parent groupIdxxx/groupId artifactIdparent-xxx/artifactId version2.0.0/version /parent
然后先使用maven插件刷新pom依赖,顺利的话,可以在maven插件中看到新的依赖包版本:
pom依赖刷新之后,再来修改工程的idea配置中的java版本,打开Project Structrue,依次修改或确认java版本:
然后我们就可以对工程进行编译,检查有没有编译错误或警告。
考虑到devops的需要,你可能需要一个maven编译脚本,要注意java版本,如下所示:
#!/bin/bash export JAVA_HOME=/usr/java/jdk-17.0.3+7 mvn -version mvn clean install package
注意这里指定了JAVA_HOME,maven编译时会用到这个环境变量,因此指定为JDK17的安装目录。本地环境安装有多个JDK版本时要特别注意这一点。
如果是springboot工程,编译成功之后就可以启动服务:
#!/bin/bash JAVA_HOME=/usr/java/jdk-17.0.3+7 JAR_PATH=$(find target -name "*.jar") ${JAVA_HOME}/bin/java -jar "${JAR_PATH}"
2.5 编译与运行时遇到的问题
在编译工程以及启动springboot服务时,可能会遇到以下问题。
2.5.1 JDK模块内API未导出问题
前面说过,Java16和Java17中有一些增强Java内部封装的新特性,该特性加强了对一些以前暴露出来但其实很不安全的关键API的封装,即你不再能从外部访问这些内部API。而java的生态圈中有很多底层的类库比如lombok在以前的版本中会调用到这些内部API。那么在Java17以后将不再能调用它们,所以会有不兼容的问题。
这种问题的典型错误信息:
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:compile (default-compile) on project api-brood-base: Fatal error compiling: java.lang.IllegalAccessError: class lombok.javac.apt.LombokProcessor (in unnamed module @0x5740ff5e) cannot access class com.sun.tools.javac.processing.JavacProcessingEnvironment (in module jdk.compiler) because module jdk.compiler does not export com.sun.tools.javac.processing to unnamed module @0x5740ff5e - [Help 1]
这里的关键信息就是cannot access class xxx (in module jdk.xxx) because module jdk.xxx does not export xxx to xxx,一旦看到这句错误信息,就知道这是由于JDK加强了内部API的封装所导致的不兼容问题。
解决起来很简单,找个新版本就行了。以lombok为例,升级到版本1.18.24即可。
其他类库的包也有可能出现类似的问题,解决方法一样,换用更新的兼容Java17的版本即可。
2.5.2 redisTemplate版本不兼容
如果使用了spring的redisTemplate,那么有可能出现版本不兼容,包括:
redisTemplate.delete方法编译错误,方法参数的泛型发生了变化。
// 版本升级前编译OK,升级后编译错误 redisTemplate.delete(CollectionUtils.arrayToList(key)); // 版本升级后修改如下 redisTemplate.delete(Arrays.asList(key));
GenericObjectPoolConfig的setMaxWaitMillis被废弃不再推荐使用,用setMaxWait代替:
GenericObjectPoolConfig? genericObjectPoolConfig = new GenericObjectPoolConfig(); ... // genericObjectPoolConfig.setMaxWaitMillis(redisProps.getPool().getMaxWait()); genericObjectPoolConfig.setMaxWait(Duration.ofMillis(redisProps.getPool().getMaxWait()));
2.5.3 jackson版本不兼容
spring默认使用的json工具类库jackson,它的ObjectMapper的enableDefaultTyping被废弃不再推荐使用,使用activateDefaultTyping代替
具体代码如下所示:
ObjectMapper om = new ObjectMapper(); // om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); om.activateDefaultTyping(om.getPolymorphicTypeValidator(), ObjectMapper.DefaultTyping.NON_FINAL);
2.5.4 循环依赖问题
springboot的新版本默认不再支持bean的循环依赖,因此项目中有循环依赖的bean的话,会报错,例如:
The dependencies of some of the beans in the application context form a cycle: xxxxxxxxx ┌─────┐ | xxxService1 (field private com.gcsoft.brood.sentry.service.XxxService2 com.gcsoft.brood.sentry.service.xxxService1.xxxService2) ↑ ↓ | xxxService2 (field private com.gcsoft.brood.sentry.service.XxxService1 com.gcsoft.brood.sentry.service.XxxService2.xxxService1) └─────┘ Action: Relying upon circular references is discouraged and they are prohibited by default. Update your application to remove the dependency cycle between beans. As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true.
最好的对应方式是消去bean之间的循环依赖,否则就需要显式声明允许bean的循环依赖,在application.yml中加入属性:
spring: main: allow-circular-references: true
2.5.5 缺少spring.config.import配置
如果在pom工程中依赖了springcloud的相关jar,但并没有使用springcloud相关的config配置,那么在启动springboot服务时可能会失败:
No spring.config.import property has been defined Action: Add a spring.config.import=configserver: property to your configuration. If configuration is not required add spring.config.import=optional:configserver: instead. To disable this check, set spring.cloud.config.enabled=false or spring.cloud.config.import-check.enabled=false.
按照提示,在application.yml中加入属性:
spring: cloud: config: enabled: false
2.5.6 jetty版本冲突
springboot版本升级后,内嵌的jetty版本也升级了。由于某些第三方jar使用了低版本的jetty的某些包,即使springboot没有使用jetty,也依然会在运行时发生jetty的不兼容问题:
java.lang.ClassNotFoundException: org.eclipse.jetty.server.RequestLog$Writer
这里可以选择升级第三方jar。
或者直接去除第三方jar对jetty的依赖:
dependency groupIdorg.apache.hive/groupId artifactIdhive-jdbc/artifactId version${hive.version}-${cdh.version}/version exclusions exclusion artifactIdjetty-all/artifactId groupIdorg.eclipse.jetty.aggregate/groupId /exclusion /exclusions /dependency
2.6 docker镜像
在各个工程完成升级,编译成功,并简单运行OK之后,开始做docker镜像的升级工作。
毕竟现在都在云端跑服务了。。。
这里从Docker Hub上找了与开发使用的openJDK版本一致的docker镜像,也是由eclipse的Adoptium社区提供的。
其实没有必要,其他openJDK17版本的docker镜像也是一样的,单纯的强迫症而已。。。
docker pull eclipse-temurin:17.0.3_7-jdk-alpine
对应docker hub地址:
Docker Hub
在这个openJDK17镜像的基础上,修改了时区与语言等信息,安装了bash与telnet,DockerFile如下:
# 指定基础镜像,在其上进行定制(这里是 eclipse-temurin:17.0.3_7-jdk-alpine 的镜像) FROM eclipse-temurin:17.0.3_7-jdk-alpine # 定制环境变量 ENV TIME_ZONE=Asia/Shanghai \ LANG=en_US.UTF-8 \ LANGUAGE=en_US.UTF-8 \ LC_ALL=en_US.UTF-8 # RUN在build镜像时执行,每RUN一次就会构成一层新的镜像。 # 因此有多个命令要执行时,用""连接写在一起。 RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories \ apk add --no-cache tzdata \ echo "${TIME_ZONE}" /etc/timezone \ ln -sf /usr/share/zoneinfo/${TIME_ZONE} /etc/localtime \ apk add --no-cache bash bash-doc bash-completion busybox-extras
原始的eclipse-temurin:17.0.3_7-jdk-alpine有335M,添加了tzdata,bash,busybox-extras(telnet)之后,大小是340.8M。。。完整的JDK镜像就是这么大。。。如果生产环境不需要JDK,那么可以用JRE作成的镜像,会小不少,但是缺失了很多JDK工具。
用这个DockerFile做成一个新的openJDK17镜像,命名为xxx/base-openjdk17:jdk-17.0.3_001,而各个springboot工程的DockerFile如下所示:
# 指定基础镜像 FROM xxx/base-openjdk17:jdk-17.0.3_001 # JDK11开始支持: -XX:+UseContainerSupport 使JVM能够感知容器资源, -XX:InitialRAMPercentage 初期容器内存占比, -XX:MaxRAMPercentage 最大容器内存占比 ENV JAVA_OPTS="-XX:+UseContainerSupport -XX:InitialRAMPercentage=50 -XX:MaxRAMPercentage=80" # 复制上下文目录下的target/*.jar 到容器里 ADD target/*.jar app.jar # 指定容器启动程序及参数 ENTRYPOINT "CMD" ENTRYPOINT java ${JAVA_OPTS} -jar /app.jar
该DockerFile位于springboot工程根目录下。
打进了springboot fat jar的镜像会变得更大,一般都会有400M以上。。。
三、小结
总的来说,Java11到Java17的升级比较顺利,只有少数依赖包对应版本需要升级。另外就是springboot的升级可能导致需要添加少量配置,比如显式允许bean的循环依赖
java代码的jdk版本的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于jdk的版本都有哪些、java代码的jdk版本的信息别忘了在本站进行查找喔。






