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的超类
所有用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 */ @Deprecated public String username() { return this.username; } public Integer age() { return this.age; }}
具体的作用域须要依据注解上的@Target
元注解的定义域来断定。
总结
明天介绍了如何疾速集成Java 17,而且不影响已有的我的项目。借着这个机会也对Record
类进行了介绍和解说,心愿在你首次接触这种新定义的时候可能帮忙你。原创不易,还请多多关注、点赞、再看、转发。
关注公众号:Felordcn 获取更多资讯
集体博客:https://felord.cn