一、Oracle官网下载JDK14
下载链接:https://www.oracle.com/java/technologies/javase-jdk14-downloads.html
双击JDK 14.0.2.pkg安装,安装完后,查看安装目录
/Library/Java/JavaVirtualMachines/
二、双JDK环境配置
(1)编辑配置文件
appledeMacBook-Pro:~ apple$ vim ~/.bash_profile
(2)添加如下配置
#配置alias方式切换jdk8和jdk14
export JAVA_8_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home
export JAVA_14_HOME=/Library/Java/JavaVirtualMachines/jdk-14.0.2.jdk/Contents/Home
# 默认为JDK8
JAVA_HOME=$JAVA_8_HOME
alias jdk14="export JAVA_HOME=$JAVA_14_HOME"
alias jdk8="export JAVA_HOME=$JAVA_8_HOME"
(3)保存后,使配置文件生效
appledeMacBook-Pro:~ apple$ vim ~/.bash_profile
appledeMacBook-Pro:~ apple$ source ~/.bash_profile
appledeMacBook-Pro:~ apple$
三、双JDK环境验证
(1)默认JDK8,使用java -version验证下
(2)使用jdk14切换jdk版本
四、构建Maven项目,添加jdk14并设置最新语言特性
(1)添加JDK
(2)直接选目录,注意:JDK11+以上,jdk目录下是没有jre目录的,这个不影响
(3)调整pom.xml文件内容如下
<!-- 定义版本 -->
<properties>
<java.version>14</java.version>
<jdk.version>14</jdk.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<!-- 编译时的编码 -->
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
<junit.version>4.12</junit.version>
<skipTests>true</skipTests>
</properties>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<!-- Compile -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${jdk.version}</source>
<target>${jdk.version}</target>
<encoding>${project.build.sourceEncoding}</encoding>
<showWarnings>true</showWarnings>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
(4)分别配置项目和模块的语言级别,为了使用JDK14最新特性,必须正确指定!
五、JDK14新特性代码说明
完整代码:
package com.appleyk;
/**
* <p>越努力,越幸运</p>
*
* @author appleyk
* @version V.0.1.1
* @blob
* @date created on 1:24 下午 2020/9/2
*/
public class NewFeatureTest {
public static void main(String[] args) {
/**1 instanceof判断类型的时候,默认将类型进行转换,而且还可以追加转换后的对象操作*/
A a = new B(1,"hello","jd=14");
if(a instanceof B b && b.tags.contains("jdk")){
System.out.println(b.tags);
}else {
System.out.println("不符合要求");
}
/**2.1 第一种方式:switch语句更加高逼格,支持lambda表达式*/
int age = 6;
switch (age) {
case 1, 2, 3, 4, 5 -> System.out.println("幼儿园");
case 6 -> System.out.println("一年级");
case 7 -> System.out.println("二年级");
case 8 -> System.out.println("三年级");
default -> System.out.println("其他");
}
/**2.2 第二种方式:switch语句更加高逼格,支持lambda表达式*/
age = 10;
System.out.println(
switch(age){
case 1, 2, 3, 4, 5 -> "幼儿园";
case 6 -> "一年级";
case 7 ->"二年级";
case 8 -> "三年级";
default -> "其他";
}
);
/**3 增加了"轻量级"的类定义,通过record声明记录体*/
User user= new User(1,"appleyk",new Address("江苏省苏州市"));
System.out.println(user);
user.sayHello();
/**4 增强text blobs块功能,省去+操作符*/
String xml = """
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
""";
System.out.println("xml ->\n"+xml);
/**5 异常提示更加精确,需要配置VM options,加上:-XX:+ShowCodeDetailsInExceptionMessages */
User npe = new User(2,"appleyk",null);
System.out.println(npe.address().address());
}
}
class A {
int id;
String name;
public A(int id, String name) {
this.id = id;
this.name = name;
}
}
class B extends A {
String tags;
public B(int id, String name, String tags) {
super(id, name);
this.tags = tags;
}
}
/**利用record关键字创建轻量级类--数据结构,用来替代一些内部静态类繁琐的定义过程*/
/**注意record声明的记录是final类型的,字段也是,所以记录不存在继承,字段一旦初始化后不允许被修改*/
record Address(String address){}
record User(int id,String name,Address address){
public User{}
public void sayHello(){
System.out.println("你好,"+name);
}
}
(1)instanceof 功能增强
不仅可以判断x是否是y类型,还可以默认将其进行转换赋到z身上,同时还可以对z进行操作
/**1 instanceof判断类型的时候,默认将类型进行转换,而且还可以追加转换后的对象操作*/
A a = new B(1,"hello","jd=14");
if(a instanceof B b && b.tags.contains("jdk")){
System.out.println(b.tags);
}else {
System.out.println("不符合要求");
}
输出结果:
(2)switch语句功能增强
不得不说这个功能挺装逼的,整的花里胡哨,虽说这样写性能倒不会提升,但起码代码量是省了不少
/**2.1 第一种方式:switch语句更加高逼格,支持lambda表达式*/
int age = 6;
switch (age) {
case 1, 2, 3, 4, 5 -> System.out.println("幼儿园");
case 6 -> System.out.println("一年级");
case 7 -> System.out.println("二年级");
case 8 -> System.out.println("三年级");
default -> System.out.println("其他");
}
/**2.2 第二种方式:switch语句更加高逼格,支持lambda表达式*/
System.out.println(
switch(age){
case 1, 2, 3, 4, 5 -> "幼儿园";
case 6 -> "一年级";
case 7 ->"二年级";
case 8 -> "三年级";
default -> "其他";
}
);
输出结果:
(3)增加record关键字,用来创建轻量级的”类“,即单纯的用来作为数据载体的简单类
不得不说这个新功能到是很ok的,起码写的时候很简洁,用起来也很方便,和类实例的用法没什么差别,唯一区别就是:
(3.1)用record定义的类是final类型的,不可以被继承,且它的字段是private final类型的,也就是初始化一次后,后面就不允许被修改了。
(3.2)用record定义的类,相比class定义的类来说,会省去不少的代码量,因为jdk会默认将getter、hashCode和toString等方法给实现了,这个功能有点类似于Lombok插件
/**利用record关键字创建轻量级类--数据结构,用来替代一些内部静态类繁琐的定义过程*/
/**注意record声明的记录是final类型的,字段也是,所以记录不存在继承,字段一旦初始化后不允许被修改*/
record Address(String address){}
record User(int id,String name,Address address){
public void sayHello(){
System.out.println("你好,"+name);
}
}
/**3 增加了"轻量级"的类定义,通过record声明记录体*/
User user= new User(1,"appleyk",new Address("江苏省苏州市"));
System.out.println(user);
user.sayHello();
利用idea自带的插件,反编译User记录类,瞅一眼
图1 -- Java Bytecode Decompiler
图2 -- 显示字节码
图3 -- 很明显,record关键字修饰的User类反编译后,实际上就是一个继承自Record类的final类
图4 -- JDK14中的抽象类Record
图5 -- 明明没有实现toString和hashCode方法,反编译查看字节码的时候却出现了
输出结果:
(4)增强Text Blocks块功能,让带有排版、布局、格式的文本可以直接粘贴
这个功能挺不错的,至少不用对文本进行重新排版了,复制过来是什么格式,直接在""" """之间粘贴上即可
/**4 增强text blobs块功能,省去+操作符*/
String xml = """
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
""";
System.out.println("xml ->\n"+xml);
输出结果:
(5)空指针异常提示信息更加精准,方便开发人员排查错误
这个功能还行吧,因为一旦发生NullPointerException的话,JDK也会提示我们错误代码在哪一行,基本上我们定位到这一行代码就知道怎么回事了,所以要不要这个功能都无所谓;但是JDK14中,这个不仅可以告诉你异常发生在哪一行,它还把谁null也给指出来了,也就是说,在你定位到那行代码之前,控制台打印的异常消息就已经告诉你异常真相了!
/**5 异常提示更加精确,需要配置VM options,加上:-XX:+ShowCodeDetailsInExceptionMessages */
User npe = new User(2,"appleyk",null);
System.out.println(npe.address().address());
(5)其他新特性略