快速无副作用搭建Java 17环境并玩转Record特性

举报
码农小胖哥 发表于 2022/04/01 01:05:28 2022/04/01
【摘要】 Java 17现在已经发布,不少同学蠢蠢欲试,但是又担心配置新的JDK会影响现在的项目环境。今天介绍一个项目级别的JDK配置方法。让你先人一步快速入门Java 17,同时也不会影响原有项目。 项目快速集成Java 17 IDEA 集成 Java 17 ❝ 在发文前,亚马逊的Corretto JDK...

4050207b001925fb72dc308a3dd1121a.gif

Java 17现在已经发布,不少同学蠢蠢欲试,但是又担心配置新的JDK会影响现在的项目环境。今天介绍一个项目级别的JDK配置方法。让你先人一步快速入门Java 17,同时也不会影响原有项目。

项目快速集成Java 17

60672a2663bd65300cd22605c453f05a.png IDEA 集成 Java 17

在发文前,亚马逊的Corretto JDK 17 、Zulu JDK 17 都已经加入了豪华午餐。

选完就可以下载Java 17的JDK了。可能是因为刚发布的缘故,实在太慢了。所以我直接到Open JDK 的官网的JDK17下载了一份。解压到Windows当前用户文件夹路径下(我的是C:\Users\n1\.jdks),之所以解压到.jdks下是因为IDEA的下载目标文件夹就是这个文件夹,方便IDEA自动检出。

a0a7ef9f4e1504bbf8aaa9637201b6b0.png 解压完成的效果

这里不需要重新配置Java环境变量,都是项目级别的Java版本控制,不会对你的其它项目造成影响。

然后新建一个Maven项目(也可以是普通项目或者Gradle项目),这个时候你还不能愉快地玩耍。你需要确定两件事情。

语言级别

调整JDK的语言级别为Java 17 ,在IDEA下按快捷键 Ctrl+Alt+Shift+S 呼出下面的对话框并将Language Level修改为17

02af70aed3f2620ca1568e8904ed4e57.png 修改项目 JDK Level

字节码版本

编译器的字节码版本也需要调整为17。在IDEA中按下快捷键 Ctrl+Alt+S 在图示中的位置进行修改。

4d7b7538efc36db981b067e8af5daef2.png 修改编译器的字节码版本

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的实现都覆写了equalshashCodetoString三个方法。

如何判断一个类是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类进行了介绍和讲解,希望在你初次接触这种新定义的时候能够帮助你。原创不易,还请多多关注、点赞、再看、转发。

文章来源: felord.blog.csdn.net,作者:码农小胖哥,版权归原作者所有,如需转载,请联系作者。

原文链接:felord.blog.csdn.net/article/details/120359784

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。