文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Java原生支持Lombok了,你知道吗?

2024-11-28 15:19

关注

我们在开发时会借助Lombok快速填充POJO类的模板方法,比如:getter、setter、equals、hashCode等,引入这个组件的原因是方便,一个注解就可以代理一堆的模板方法。

从Java16开始,我们可以借助Record类型实现相同的功能了,接下来,我们详细看下这个类型。

Record是Java中的一种特殊类,旨在为程序员提供一种高效且简便的方式实现POJO类。Record类型通过关键字record实现。

一、Java中的Record类是什么?

在Java项目开发中,作为开发者,我们常常编写服务类、安全类或其他基础类,这些类本质上是功能性的。同样,程序员也经常编写仅用于承载数据的类,即POJO类。

例如,假设客户端向服务器请求某个人的“id”和“name”等数据,服务器会以相应的数据进行响应。

由于Java中一切皆为对象,所以必然存在某个类来承载这些数据,服务器会将该类的对象返回给客户端,该对象的唯一目的就是将数据从服务器传递到客户端。

然而,编写这样一个数据类,即便它可能只是一个简单的POJO,也会包含大量的模板代码,比如私有字段、构造函数、getter和setter方法、hashCode()、equals()和toString()方法。

由于Java语言的冗长特性,一个简单的承载类会因大量不必要的代码而变得臃肿。

这些弊端促使了一种特殊类型的类Record的诞生。该类能够聚合(或持有)一组值,无需编写自动生成样板代码,可以说是一种高效的数据对象构建方式。

虽然,即使没有Record类型,我们也能写好代码,比如借助IDEA的模板生成,比如借助Lombok的注解,但是,原生支持的能力,在便利性和效率方面,可以给代码注入新的灵魂。

我们看下以前的写法:

import java.util.Objects;

public class Person {
    private int id;
    private String name;

    public Person() {}

    public Person(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass()!= o.getClass()) return false;
        Person person = (Person) o;
        return getId() == person.getId() && getName().equals(person.getName());
    }

    @Override
    public int hashCode() {
        return Objects.hash(getId(), getName());
    }

    @Override
    public String toString() {
        return "Person{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

是不是看着都不想写了。

二、如何在Java中创建Record类?

Java中的Record类由关键字record支持,语法为:

record recordName(list-of-components) {
    //可选语句
}

以record开头,后面跟着类名和参数列表。此时,我们可以把前面的Person改写为:

record Person(int id, String name){}

一下子就清爽了。

使用起来和原来没有太多差异:

Person p1 = new Person(1, "Peter Parker");

在编译过程中,编译器会自动提供存储数据所需的元素、构造函数、访问数据的getter方法、toString()、equals()和hashCode()方法。因此,虽然没有写下面这些方法,也能够正常使用。

Person p1 = new Person(1, "Peter Parker");
Person p2 = new Person(2, "Spiderman");
System.out.println(p1.toString());
System.out.println(p1.equals(p2));
System.out.println(p1.name());

关于上述代码示例,有以下几个要点需要注意:

三、Java中的规范构造函数

在Record中,如果需要定义规范构造函数,需要按照预设格式定义。我们有两种方式来声明我们自己的实现。

方式一、常用的规范构造函数:

record Invoice(String id, float amount) {
    static String prefix = String.valueOf(Calendar.getInstance().get(Calendar.YEAR))
            + String.valueOf(Calendar.getInstance().get(Calendar.MONTH) + 1);

    public Invoice(String id, float amount) {
        this.id = prefix + id.trim();
        this.amount = amount;
    }
}

方式二、紧凑构造函数。在紧凑构造函数中,签名声明是隐式的。我们只需提供Record类名作为构造函数,不带任何参数。这种类型的构造函数具有所有参数的隐式声明,并且会自动将传递给记录组件的值赋给相应参数。此外,在紧凑构造函数中,不使用this关键字。

record Invoice(String id, float amount) {
    static String prefix = String.valueOf(Calendar.getInstance().get(Calendar.YEAR))
            + String.valueOf(Calendar.getInstance().get(Calendar.MONTH) + 1);
    public Invoice {
        id = prefix + id.trim();
        amount = amount;
    }  
}

四、Java中的非规范构造函数

除了规范构造函数,我们还可以定义非规范构造函数。比如:当我们只想用默认初始化一个字段,此时,我们可以编写一个非规范构造函数。

非规范构造函数的关键要求是,构造函数必须使用this关键字调用记录中的另一个规范构造函数。

以下是一个简单示例:

record Invoice(String id, float amount) {
    static String prefix = String.valueOf(Calendar.getInstance().get(Calendar.YEAR))
            + String.valueOf(Calendar.getInstance().get(Calendar.MONTH) + 1);
    public Invoice {
        id = prefix + id.trim();
        amount = amount;
    }

    public Invoice(String id) {
        this(id, 0.0f);
    }
}

非规范构造函数就像是预设默认值的一种实现。

五、Java Record类代码示例

最后,我们来个示例代码,展示了如何在Java中使用Record类、规范构造函数和非规范构造函数:

record Invoice(String id, float amount) {
    static String prefix = String.valueOf(Calendar.getInstance().get(Calendar.YEAR))
            + String.valueOf(Calendar.getInstance().get(Calendar.MONTH) + 1);
    public Invoice {
        id = prefix + id.trim();
        if (amount < 0)
            throw new IllegalArgumentException("-ve values not allowed");
        amount = amount;
    }

    public Invoice(String id) {
        this(id, 0.0f);
    }
}

public class App {
    public static void main(String[] args) {
        float[] amt = {400.00f, 600.00f, 300.00f, 700.00f, 600.00f};
        Invoice[] invoice = new Invoice[5];
        for (int i = 0; i < invoice.length; i++)
            invoice[i] = new Invoice(String.valueOf(i + 1), amt[i]);
        for (int i = 0; i < invoice.length; i++)
            System.out.println(invoice[i].toString());
    }
}

文末总结

Record类和record关键字的引入,极大地提升了定义类的便捷性,打破了Java语言规范中POJO类冗长的声明。我们可以不用他,但是要知道其用法。就像是Java8的stream一样,Record类也有很大魅力。

来源:看山的小屋内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯