18岁以上站长统计,广州天河建站公司,网站建设氺金手指排名11,网站文章内链2020年3月17日发布#xff0c;Java正式发布了JDK 14 #xff0c;目前已经可以开放下载。在JDK 14中#xff0c;共有16个新特性#xff0c;本文主要来介绍其中的一个特性#xff1a;JEP 359: Records官方吐槽最为致命早在2019年2月份#xff0c;Java 语言架构师 Brian Goe… 2020年3月17日发布Java正式发布了JDK 14 目前已经可以开放下载。在JDK 14中共有16个新特性本文主要来介绍其中的一个特性JEP 359: Records官方吐槽最为致命早在2019年2月份Java 语言架构师 Brian Goetz曾经写过一篇文章(http://cr.openjdk.java.net/~briangoetz/amber/datum.html )详尽的说明了并吐槽了Java语言他和很多程序员一样抱怨“Java太啰嗦”或有太多的“繁文缛节”他提到开发人员想要创建纯数据载体类(plain data carriers)通常都必须编写大量低价值、重复的、容易出错的代码。如构造函数、getter/setter、equals()、hashCode()以及toString()等。以至于很多人选择使用IDE的功能来自动生成这些代码。还有一些开发会选择使用一些第三方类库如Lombok等来生成这些方法从而会导致了令人吃惊的表现(surprising behavior)和糟糕的可调试性(poor debuggability)。那么Brian Goetz 大神提到的纯数据载体到底指的是什么呢。他举了一个简单的例子final 这里面的Piont其实就是一个纯数据载体他表示一个点中包含x坐标和y坐标并且只提供了构造函数以及一些equals、hashCode等方法。于是BrianGoetz大神提出一种想法他提到Java完全可以对于这种纯数据载体通过另外一种方式表示。其实在其他的面向对象语言中早就针对这种纯数据载体有单独的定义了如Scala中的case、Kotlin中的data以及C#中的record。这些定义尽管在语义上有所不同但是它们的共同点是类的部分或全部状态可以直接在类头中描述并且这个类中只包含了纯数据而已。于是他提出Java中是不是也可以通过如下方式定义一个纯数据载体呢record Point(int x, int y) { }神说要用record于是就有了就像大神吐槽的那样我们通常需要编写大量代码才能使类变得有用。如以下内容toString()方法hashCode() and equals()方法Getter 方法一个共有的构造函数对于这种简单的类这些方法通常是无聊的、重复的而且是可以很容易地机械地生成的那种东西(ide通常提供这种功能)。当你阅读别人的代码时可能会更加头大。例如别人可能使用IDE生成的hashCode()和equals()来处理类的所有字段但是如何才能在不检查实现的每一行的情况下确定他写的对呢?如果在重构过程中添加了字段而没有重新生成方法会发生什么情况呢?大神Brian Goetz提出了使用record定义一个纯数据载体的想法于是Java 14 中便包含了一个新特性EP 359: Records 作者正是 Brian GoetzRecords的目标是扩展Java语言语法Records为声明类提供了一种紧凑的语法用于创建一种类中是“字段只是字段除了字段什么都没有”的类。通过对类做这样的声明编译器可以通过自动创建所有方法并让所有字段参与hashCode()等方法。这是JDK 14中的一个预览特性。一言不合反编译Records的用法比较简单和定义Java类一样record Person (String firstName, String lastName) {}如上我们定义了一个Person记录其中包含两个组件:firstName和lastName以及一个空的类体。那么这个东西看上去也是个语法糖那他到底是怎么实现的那我们先尝试对他进行编译记得使用--enable-preview参数因为records功能目前在JDK 14中还是一个预览(preview)功能。14 Person.java如前所述Record只是一个类其目的是保存和公开数据。让我们看看用javap进行反编译将会得到以下代码:public 通过反编译得到的类我们可以得到以下信息1、生成了一个final类型的Person类(class)说明这个类不能再有子类了。2、这个类继承了java.lang.Record类这个我们使用enum创建出来的枚举都默认继承java.lang.Enum有点类似3、类中有两个private final 类型的属性。所以record定义的类中的属性都应该是private final类型的。4、有一个public的构造函数入参就是两个主要的属性。如果通过字节码查看其方法体的话其内容就是以下代码你一定很熟悉public Person(String firstName, String lastName) {5、有两个getter方法分别叫做firstName和lastName。这和JavaBean中定义的命名方式有区别或许大神想通过这种方式告诉我们record定义出来的并不是一个JavaBean吧。6、还帮我们自动生成了toString(), hashCode() 和 equals()方法。值得一提的是这三个方法依赖invokedynamic来动态调用包含隐式实现的适当方法。还可以这样玩前面的例子中我们简单的创建了一个record那么record中还能有其他的成员变量和方法吗我们来看下。1、我们不能将实例字段添加到record中。但是我们可以添加静态字段。record Person (String firstName, String lastName) {2、我们可以定义静态方法和实例方法可以操作对象的状态。record Person (String firstName, String lastName) {3、我们还可以添加构造函数。record Person (String firstName, String lastName) {所以我们是可以在record中添加静态字段/方法的但是问题是我们应该这么做吗请记住record推出背后的目标是使开发人员能够将相关字段作为单个不可变数据项组合在一起而不需要编写冗长的代码。这意味着每当您想要向您的记录添加更多的字段/方法时请考虑是否应该使用完整的类来代替它。总结record 解决了使用类作为数据包装器的一个常见问题。纯数据类从几行代码显著地简化为一行代码。但是record目前是一种预览语言特性这意味着尽管它已经完全实现但在JDK中还没有标准化。那么问题来了如果你用上了Java 14之后你还会使用Lombok吗哦不你可能短时间内都用不上因为你可能Java 8都还没用熟~PS最近Java 14发布了很多新功能很多特性还是比较有意思的这个是本系列的第一篇文章欢迎大家关注公众号Java之道后续文章写好后会第一时间发出。参考资料https://openjdk.java.net/jeps/359https://dzone.com/articles/a-first-look-at-records-in-java-14https://aboullaite.me/java-14-records/http://cr.openjdk.java.net/~briangoetz/amber/datum.html关于作者Hollis一个对Coding有着独特追求的人现任阿里巴巴技术专家个人技术博主技术文章全网阅读量数千万《程序员的三门课》联合作者。推荐阅读接口默认方法是什么鬼HTTPS 的 7 次握手以及 9 倍时延Java堆内存是线程共享的面试官你确定吗2020年3月全国程序员工资统计平均工资13820元喜欢我可以给我设为星标哦好文章我 在看