乐趣区

关于java:快速无副作用搭建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 的超类

所有用 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 类进行了介绍和解说,心愿在你首次接触这种新定义的时候可能帮忙你。原创不易,还请多多关注、点赞、再看、转发。

关注公众号:Felordcn 获取更多资讯

集体博客:https://felord.cn

退出移动版