JDK 14的新特性:Lombok的终结者record

简介

自从面向对象产生之后,程序界就开始了新的变化,先是C发展到了C++,后面java横空出世,大有一统江湖的趋势。

面向对象凭借其结构化的特点和在大型项目中的优势,一路蓬勃发展到今。面向对象不是不好,但是太繁琐。

比如我们要定义一个简单的存储数据的结构,比如说User。除了要定义其内部的具体字段以外,我们还要定义get set方法,定义构造函数,equals(), hashCode(), toString()等。

为了解决这个问题,也产生了很多解决方案,比如Lombok,可以通过注解就自动生成特定的存取方法和构造函数。但是Lombok生成的代码看不到,在代码调试方面有一定的劣势。

终于JDK 14为我们带来了record,虽然还是预览特性,但是今天我们一览为快。

新的Record类型

Record是一种轻量级的class,可以看做是数据结构体。和scala中的case有点相似。

举个自定义User的例子看一下Record是怎么用的:

public record Address(
String addressName,
String city
) {
}
public record CustUser(
String firstName,
String lastName,
Address address,
int age
) {}

上面我们定义了两个类,CustUser和Address。CustUser中引用了Address。

Record和普通的类的区别就在于Record多了一个括号括起来的定义的字段。

Record类默认是final的,里面的字段默认是private final的。

探讨Record的秘密

要想知道Record到底是怎么工作的,我们可以使用javap来对编译好的class文件反编译,运行javap CustUser,可以得到下面的结果:

警告: 二进制文件CustUser包含com.flydean.records.CustUser
Compiled from "CustUser.java"
public final class com.flydean.records.CustUser extends java.lang.Record {
public com.flydean.records.CustUser(java.lang.String, java.lang.String, com.flydean.records.Address, int);
public java.lang.String toString();
public final int hashCode();
public final boolean equals(java.lang.Object);
public java.lang.String firstName();
public java.lang.String lastName();
public com.flydean.records.Address address();
public int age();
}

上面可以看到final class CustUser继承自java.lang.Record。

并且自动添加了默认带有所有字段的构造函数。各个自动的获取方法,并实现了toString,hashCode和equals方法。

天啦,太完美了,我们想要的它居然都有。

如果上面的javap还不是很清楚的话,大家可以借助IDE的反编译功能,打开CustUser.class文件看一看:

public final class CustUser extends java.lang.Record {
private final java.lang.String firstName;
private final java.lang.String lastName;
private final com.flydean.records.Address address;
private final int age; public CustUser(java.lang.String firstName, java.lang.String lastName, com.flydean.records.Address address, int age) { /* compiled code */ } public java.lang.String toString() { /* compiled code */ } public final int hashCode() { /* compiled code */ } public final boolean equals(java.lang.Object o) { /* compiled code */ } public java.lang.String firstName() { /* compiled code */ } public java.lang.String lastName() { /* compiled code */ } public com.flydean.records.Address address() { /* compiled code */ } public int age() { /* compiled code */ }
}

注意,上面的反编译我们可以看到,record中的所有字段都是final的,只能在初始化的时候设置。并且方法里面也没有提供其他可以改变字段内容的方法。

所以我们得出了一个震世惊俗的结论:record是immutable的。

record扩展

上面的例子中我们只使用了小括号里面的内容,大括号还是空的呀。可不可以像其他正常的类一样,添加点方法或者构造函数进去呢?

答案是肯定的。

先看一个整体的方案:

public record CustUserWithBody(
String firstName,
String lastName,
Address address,
int age
) {
public String fullName(){
return firstName+ lastName;
} public CustUserWithBody{
if (age < 18) {
throw new IllegalArgumentException( "男大当婚,女大当嫁,18岁未到,不许出嫁!");
}
}
}

我们在record的主题中,定义了一个方法和一个构造函数。

先看这个方法,在方法中我们可以访问到record中定义的变量,但是千万不要尝试去修改他们,因为他们是final的,你会得到一个变异错误。

再看这个构造函数,这个构造函数没有小括号,只有大括号,这种构造函数叫做Compact constructor。你无法在record中定义正常的构造函数,因为会得到一个编译错误。

在这个Compact constructor中,我们可以对定义的字段进行数据校验。如上所述。

总结

record是个好东西,希望能够出现在JDK的正式版本中。

最后,很多人可能有个疑问,JDK14声势这么浩大,怎么感觉大的颠覆性的更新也没有太多。

那么我以一个过来人的身份来回答一下这个问题:第一,JDK肯定要保持稳定,新特性都是次要的,稳定压倒一切。所以6个月说长不长说短不短的时间里面注定不会有大的更新。第二,欧美公司的通病,在欧美公司工作不要太潇洒,不但可以不打卡,在家上班,上班也是大大小小的会议开个不停,最后留下来写程序的时间自然不会很多。牛人大神有很多,浑水摸鱼的也不少。效率的话自然比不了国内的996+857了。

本文的例子https://github.com/ddean2009/learn-java-base-9-to-20

欢迎关注我的公众号:程序那些事,更多精彩等着您!

更多内容请访问 www.flydean.com

JDK14的新特性:Lombok的终结者record的更多相关文章

  1. JDK14的新特性-Switch新功能

    2020年3月17日,Oracle正式发布了JDK14版本,共新增了16项新特性 本文重点写一下关于switch的新功能: switch 表达式扩展了 switch 语句,使其不仅可以作为语句(sta ...

  2. JDK14的新特性

    文章目录 虽然JDK13在今年的9月17号才发布,但是丝毫不会影响到下一个版本JDK14的开发工作.听说官方定的新功能马上就要官宣了,我们这里不妨来提前推断一下. 在9月17号的发布中,Oracle提 ...

  3. Jdk14 都要出了,Jdk9 的新特性还不了解一下?

    Java 9 中最大的亮点是 Java 平台模块化的引入,以及模块化 JDK.但是 Java 9 还有很多其他新功能,这篇文字会将重点介绍开发人员特别感兴趣的几种功能. 这篇文章也是 Java 新特性 ...

  4. JDK14发布了,快来看看有什么新特性吧

    序言

  5. C# 9.0中引入的新特性init和record的使用思考

    写在前面 .NET 5.0已经发布,C# 9.0也为我们带来了许多新特性,其中最让我印象深刻的就是init和record type,很多文章已经把这两个新特性讨论的差不多了,本文不再详细讨论,而是通过 ...

  6. Java 16 新特性:record类

    以前我们定义类都是用class关键词,但从Java 16开始,我们将多一个关键词record,它也可以用来定义类.record关键词的引入,主要是为了提供一种更为简洁.紧凑的final类的定义方式. ...

  7. Java14:你需要知道的新特性

    基本介绍 2020 年 3 月 17 日,JDK / Java 14 正式 GA(General Available).这是自从 Java 采用六个月一次的发布周期之后的第五次发布. 此版本包含的 J ...

  8. 一文带你看遍 JDK9~14 的重要新特性!

    Java9 发布于 2017 年 9 月 21 日 .作为 Java8 之后 3 年半才发布的新版本,Java 9 带 来了很多重大的变化其中最重要的改动是 Java 平台模块系统的引入,其他还有诸如 ...

  9. 我还在生产玩 JDK7,JDK 15 却要来了!|新特性尝鲜

    自从 JDK9 之后,每年 3 月与 9 月 JDK 都会发布一个新的版本,而2020 年 9 月即将引来 JDK15. 恰巧 IDEA 每四五个月会升级一个较大的版本,每次升级之后都会支持最新版本 ...

随机推荐

  1. JVM基础结构与字节码执行引擎

    JVM基础结构 JVM内部结构如下:栈.堆. 栈 JVM中的栈主要是指线程里面的栈,里面有方法栈.native方法栈.PC寄存器等等:每个方法栈是由栈帧组成的:每个栈帧是由局部变量表.操作数栈等组成. ...

  2. 测试Activity和Fragment的生命周期

    Activity的生命周期有7个函数,Fragment的生命周期有11个函数. Activity生命周期除上述6个方法还有一个Restart()方法,该方法在该Activity从不可见(仍存在)到重新 ...

  3. 1045 Favorite Color Stripe (30分)(简单dp)

    Eva is trying to make her own color stripe out of a given one. She would like to keep only her favor ...

  4. 汇编刷题:根据公式 Z=(X+Y)*8-X)/4 计算Z的结果(本题将结果放在AL寄存器里)

    DATA SEGMENT X DB 10 Y DB 20 Z DB 00 DATA ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA START: MOV AX,DAT ...

  5. python selenium使用

    安装selenium #Python pip install selenium #Anaconda3 conda install selenium 下载浏览器版本对应的驱动文件 chrome chro ...

  6. Mysql fundamental knowledge

    Mysql 5.1, 5.5 are more stable than other versions. postgresql has more strict "sql standard &q ...

  7. spark 大杂烩

    累加器 val dataRdd = sc.makeRDD(List(1, 2, 3, 4), 2) var sum = 0 //累加器可以收集driver和各个excuter中累加的结果 //如果此处 ...

  8. Go语言 中文分词技术使用技巧(一)

    分词技术就是搜索引擎针对用户提交查询的关键词串进行的查询处理后根据用户的关键词串用各种匹配方法进行分词的一种技术. 中文分词(Chinese Word Segmentation)指的是将一个汉字序列( ...

  9. mysql 向上取整

    SELECT CEILING(10.0)    --->10 SELECT CEILING(10.1)    --->11

  10. AJ学IOS 之小知识之_xcode插件的删除方法_自动提示图片插件KSImageNamed有时不灵_分类或宏之类不能自动提示,

    AJ分享,必须精品 一:解决解决自动提示图片插件KSImageNamed有时不灵_分类或宏之类不能自动提示 其实,插件神马的我们自己也能写,并没有想象中的那么难,不过目前我们还是先解决当前问题 在做微 ...