快速无副作用搭建Java 17环境并玩转Record特性
Java 17现在已经发布,不少同学蠢蠢欲试,但是又担心配置新的JDK会影响现在的项目环境。今天介绍一个项目级别的JDK配置方法。让你先人一步快速入门Java 17,同时也不会影响原有项目。
项目快速集成Java 17
文章图片
在发文前,亚马逊的Corretto JDK 17 、Zulu JDK 17 都已经加入了豪华午餐。选完就可以下载Java 17的JDK了。可能是因为刚发布的缘故,实在太慢了。所以我直接到Open JDK 的官网的JDK17下载了一份。解压到Windows当前用户文件夹路径下(我的是
C:\Users\n1\.jdks
),之所以解压到.jdks
下是因为IDEA的下载目标文件夹就是这个文件夹,方便IDEA自动检出。文章图片
这里不需要重新配置Java环境变量,都是项目级别的Java版本控制,不会对你的其它项目造成影响。然后新建一个Maven项目(也可以是普通项目或者Gradle项目),这个时候你还不能愉快地玩耍。你需要确定两件事情。
语言级别
调整JDK的语言级别为Java 17 ,在IDEA下按快捷键 Ctrl+Alt+Shift+S 呼出下面的对话框并将Language Level修改为
17
。文章图片
字节码版本
编译器的字节码版本也需要调整为
17
。IDEA中按下快捷键 Ctrl+Alt+S 在图示中的位置进行修改。文章图片
Record Class 搞定了环境配置后,我们开始试一试一个最直观的、也相当有用的语法糖Record。
准确地说这不属于Java 17的新特性,最早在Java 14 中出现,在Java 16中转为正式特性。不过作为LTS版本,这依然是很重要的一个概念。我们直观一些,一个数据类传统的写法是:
public class MyRecord {
private final String username;
private final Integer age;
public MyRecord(String username, Integer age) {
this.username = username;
this.age = age;
}public String username() {
return username;
}public Integer age() {
return age;
}@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MyRecord oldRecord = (MyRecord) o;
return Objects.equals(username, oldRecord.username)
&& Objects.equals(age, oldRecord.age);
}@Override
public int hashCode() {
return Objects.hash(username, age);
}@Override
public String toString() {
return "MyRecord[" +
"username='" + username + '\'' +
", age=" + age +
']';
}
}
用
Record
就可以简化为:public record MyRecord(String username,Integer age) {
}
这样大大减少了一些模板代码,让逻辑更加清晰简单。
Record 是不可变的
Record
被用来设计传输不可变的数据。从上面的例子可以看到,一个Record
类被初始化后里面的属性是不能改变的,没有Setter方法而是通过全参数构造来初始化数据,天然线程安全。Record的超类
【快速无副作用搭建Java 17环境并玩转Record特性】所有用
Record
关键字声明的类都是java.lang.Record
的子类,这一点有点像枚举。public abstract class Record {
protected Record() {}
@Override
public abstract boolean equals(Object obj);
@Override
public abstract int hashCode();
@Override
public abstract String toString();
}
从这里也可以看出所有
Record
的实现都覆写了equals
、hashCode
、toString
三个方法。
如何判断一个类是
Record
类?
传统方法:Record.class.isAssignableFrom(MyRecord.class)
JDK提供了一个新的方法来解决这个问题:
MyRecord.class.isRecord()
值得一提的是
Class
类还提供了getRecordComponents
来获取Record
类的成员属性信息。RecordComponent[] recordComponents = MyRecord.class.getRecordComponents();
Record无法使用extends关键字
由于
Record
类的唯一的隐式超类是java.lang.Record
,Java不支持多继承,使用 extends
显式定义会导致编译错误。无法定义额外的成员变量
Record
类的成员变量只能通过构造声明。所以下面这种写法是错误的:public record MyRecord(String username,Integer age) {
privite String gender;
}
但是你可以在
Record
类中定义静态变量。定义方法时需要小心
定义方法比较开放,但是请确保你定义的方法不会破坏
Record
不可变的含义。不推荐定义Setter方法。另外注意使用注解Record
类的 Getter方法不是setXXXX
格式的。
唯一需要注意的是,在
Record
类的成员变量上使用注解可能会作用的Getter
方法上。就像这样:public record MyRecord(@Deprecated String username,Integer age) {
}
编译后:
public record MyRecord(String username, Integer age) {public MyRecord(@Deprecated String username, Integer age) {this.username = username;
this.age = age;
}public String getUsername() {return this.username;
}/** @deprecated */@Deprecatedpublic String username() {return this.username;
}public Integer age() {return this.age;
}}
具体的作用域需要根据注解上的
@Target
元注解的定义域来判定。总结 今天介绍了如何快速集成Java 17,而且不影响已有的项目。借着这个机会也对
Record
类进行了介绍和讲解,希望在你初次接触这种新定义的时候能够帮助你。原创不易,还请多多关注、点赞、再看、转发。关注公众号:Felordcn 获取更多资讯
个人博客:https://felord.cn
推荐阅读
- 六步搭建ES6语法环境
- (1)redis集群原理及搭建与使用(1)
- 桁架搭建有什么价值()
- neo4j|neo4j cql语句 快速查询手册
- VM|VM ware 的 harbor 私有仓库搭建 (Ubuntu16.04)
- PHP开发-Mac搭建ThinkPHP5.0
- 通过复盘快速成长(附模板)
- Python|Win10下 Python开发环境搭建(PyCharm + Anaconda) && 环境变量配置 && 常用工具安装配置
- sentry搭建错误监控系统(二)
- 【乐高创意作品】超智能!这款乐高搭建的除草机!