快速搭建Java 17环境并玩转Record特性 |
您所在的位置:网站首页 › per语言环境 › 快速搭建Java 17环境并玩转Record特性 |
Java 17现在已经发布,不少同学蠢蠢欲试,但是又担心配置新的JDK会影响现在的项目环境。今天介绍一个项目级别的JDK配置方法。让你先人一步快速入门Java 17,同时也不会影响原有项目。 项目快速集成Java 17IDEA 集成 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。 修改项目 JDK Level 字节码版本编译器的字节码版本也需要调整为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) { }这样大大减少了一些模板代码,让逻辑更加清晰简单。一定意义上代替了Lombok。 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类进行了介绍和讲解,希望在你初次接触这种新定义的时候能够帮助你。原创不易,还请多多关注、点赞、再看、转发。 往期推荐 一个Bug能有多大影响:亏损30亿、致6人死亡、甚至差点毁灭世界... 六成大学生认为自己毕业10年内会年入百万!网友:知乎上多了,没被社会毒打过吧! 缓存核心知识小抄,面试必备,赶紧收藏! Java 17正式发布, Oracle宣布免费提供!“版本任你发,我用Java 8”或成历史? Spring Boot 中使用@Async实现异步调用,加速任务执行! 技术交流群 最近有很多人问,有没有读者交流群,想知道怎么加入。加入方式很简单,有兴趣的同学,只需要点击下方卡片,回复“加群“,即可免费加入我们的高质量技术交流群! 点击阅读原文,送你免费Spring Boot教程! |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |