漫谈IDEA设置JDK版的背景IDEA中有很多地方可以设置JDK版,很多资深开发者并不一定知道其差异和设置后的影响。 当然本人也不完全清楚,所以需要大家一起捡柴。
如果遇到版本问题(例如编译错误或运行时提示版本错误),通常只要版本匹配就没问题。
仔细阅读本文,你会有不少收获的
可以在IDEA上设定jdk/JRE版本的地方大致看一下就可以了。 此副标题仅列出可以设置JDK版本的地方,并在后续标题下分析其作用。
1、项目结构-项目文件-项目结构. -项目,图1
2、项目结构- modules file -项目结构.-modules-sources|dependencies,图2
3、新项目结构-项目文件- newproject ssettings-structurefornewprojects .图3
4、Java Compiler中的文件设置构建,执行,部署- compiler-Java compiler,图4
(虽然Module列表可能为空,但除Maven之外的项目通常为空。 当然可以添加,但不需要添加)
5、在Run Configuration中为editconfigurations . http://www.Sina.com/)
这通常在执行main方法后出现,也可以自己添加。 有JRE版本的设定
下面介绍可以设置上述JDK/JRE版本的各个位置。
以下所说的项目是指项目工程,“项目”、“工程”、“项目工程”、“项目”都是用文件新项目…建造的
“模块”和“模块”都是项目下的模块,即使在某个项目下也可以进行文件新模块。
当然,一个项目对应一个模块,但也可以在一个项目下建立多个模块
1、项目结构-项目(图1 )只有本项目有效,其他不受影响
修改的是本项目的默认值,现有的Module不受影响(说明1 ),新的Module使用新的值
说明1 :如果将语言级别设置为项目默认值,或将模块SDK设置为项目SDK,现有模块将根据项目配置的更改进行更改
项目SDK和项目语言级别有什么区别?图5
2、项目结构-Modules (图2 )修改只影响本Module,其他不受影响
语言级别(源)。
配置IDEA使用哪个版本检查语法
对于非Maven项目,它也是编译java文件的版本; maven项目不是这里,而是Java Compiler配置的
module SDK (从属)
就是项目引入的JDK依存库。 模块SDK的更改会导致外部库的更改。
如果设置为项目默认值和项目SDK,则模块的值将根据项目的更改而变化
如果不想追随Module,则变更为其他固定值
语言级别受maven.compiler.source的影响(仅适用于maven项目):见后面
3、新项目结构-项目(图3 )用于使用新项目(继承的)设置。 只有项目设置,没有模块设置。
显而易见,这是IDEA在创建新项目时采用的配置,与项目结构的区别在于,此处的配置是全局的,即使对所有新项目都进行了此处的更改,现有项目4,Java common
非Maven项目没有模块。 在非Maven项目中,使用哪个版本编译java文件取决于语言级别的配置。
[外链图像导出失败,源
站可能有防盗链机制,建议将图片保存下来直接上传(img-bwUqloxv-1623407192147)(C:UsersxuanxiaoAppDataRoamingTyporatypora-user-imagesimage-20210611160542273.png)] 对于Maven项目,会受到 maven.compiler.target 的影响。详见后续 "关于maven的配置" <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target></properties> 5、Run Configuration里 (图5)是说运行程序用的是什么版本的 JRE
如果是用1.8编译的,JRE选1.7肯定是无法运行的,可以选择>=1.8的,比如用1.9是可以的默认的值是 Default,即跟随Module SDK (即 Modules->Dependencies->Module SDK) 补充 1、究竟Language Level是干嘛的 在非Maven项目里,这是管编译java文件用什么版本的在Maven项目里,是配置给IDEA看的,让IDEA用指定版本的语法检查你的源码。例如 JDK5 引入了泛型,可以这么写:
List<String> list = new ArrayList<String>();但是不能这么写:
List<String> list = new ArrayList<>();这个写法要到JDK7之后才可以,所以如果Language level 小于7(比如5或6),IDEA会提示你语法错误,但是改成>=7的版本就不提示错误了。所以这个配置就是告诉 IDEA用什么版本的语法检查源码,以便提示编译错误。
2、关于maven的配置 <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target></properties>maven.compiler.source 的值决定了 Language level 的配置
如果将 Language level 修改成不一致,在 reimport(刷新) Maven配置后会恢复成 maven.compiler.source 的值
maven.compiler.target 的值决定了 Java Compiler里的target bytecode version
跟上面一样,如果两者指定的版本不一致,在刷新Maven后会恢复
如果Maven项目没有上述配置,则默认都是1.5
会发生 “即使你改了 Language level 和 Java Compiler 里的 target bytecode version”,刷新后恢复成1.5
详细参考这里
最佳实践:maven项目最好有这个配置
reimport 是指这里
3、关于 System.getProperty("java.version"); 是什么版本?是JRE的版本,不是class的编译版本。
比如你的源码是jdk8编译的,如果在Run Configuration里修改为jdk9的版本,获得的值是9的版本,说明这里获得的值是JRE。
4、如何知道class是用什么版本编译的有多种方法
双击打开class文件,会显示(最方便)
用jclasslib
用javap命令
javap命令,无论用 javap -v -p Xxx.class 还是 javap -v 能看到 major version 就行
5、关于Java Compiler里有时候会空的非Maven项目默认是没有Module的 (maven项目默认会有)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-X1B3I498-1623407192155)(C:UsersxuanxiaoAppDataRoamingTyporatypora-user-imagesimage-20210611160542273.png)]
当然是可以点击+号添加的。不添加,则编译的版本跟Language level保持一致。很明显,你手动添加后也可以看到,也提示你 Same as language level
这里确实是可以改成和language level的版本不同(不过谁吃饱撑着改成版本不一),但是会导致Information:java:javacTask:源发型版本xxxxx 的错误。
6、我如何添加sdk版本?先安装,自己选择需要的版本即可,不需要都装。另外很多的jdk安装的时候会提示安装jre(少数不会,好像jdk5就不会),不需要安装,我留了一个jre8。
在 IDEA 里进行添加,
在File->New Projects Settings->Structure for New Projects…->Platform Settings->SDKs里进行添加,是全局的
或者在File->Project Structure…->Platform Settings->SDKs里进行添加,也是全局的。
常见的关于JDK版本的报错 1、Diamond types are not supported at language level ‘5’修改language level即可能可以临时解决。
diamond指钻石,即钻石符号(<>),长得像钻石吧!
所以看到diamond这个单词,就要想起这个符号,sql里也用这个表示 “不等于”。jdk5里虽然有泛型的写法,但是这种写法List<String> list = new ArrayList<>();只有jdk7之后才能用钻石符号,否则就怪怪不省略,使用 List<String> list = new ArrayList<String>();
为什么说可能是临时的解决方案?
因为对于非maven的项目,你在Project Structure里Modules里改了Language level就是改了,但是对于maven项目,你改了有可能会打回原型,必须配置
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target></properties>PS: 下面是细节,以前我以为 Diamonds 是指泛型,犯过错,曾经也稀里糊涂
举个例子,如果你的class是jdk8编译的,如果你切换成7运行。
这里的 52.0 是不支持的版本,指你的class文件是用52版本编译的,不支持。
为什么会不支持?
你用52版本编译的,肯定不能用低于52的JRE运行。这里你肯定用了<52版本的JRE在运行它。
52指 jdk8,51指 jdk7,53是 jdk9,如此类推。
解决方法:提高Module SDK的版本,由于Run Configuration里JRE的设置一般是跟随Module SDK的
3、Information:java: javacTask: 源发行版 8 需要目标发行版 1.8这个乍看错误提示似乎不太好定位问题所在,不过肯定是配置的问题。那怎么解决呢?你把本文提到的那些配置的地方,检查一下,改成一致版本。