为什么Java的记录比Lombok的数据和Kotlin的数据类更好*

2021-05-08 00:14:53

我肯定是现在你' ve全都看到了记录如何变成全吹的pojo ......

班级{私人决赛INT低;私人决赛INT高;公共(Int Low,Int High){这个.Low =低;这个。高=高; public int getlow(){返回低; public int gethigh(){返回高; @Override公共布尔等于(o){如果(这== o)返回true; if(o == null || getClass()!= o。getClass())返回false;范围=()o;返回低==范围.Low&&高==范围。高度; @Override public int hashcode(){return。哈希(低,高); @Override Public ToString(){返回" [" +低+&#34 ;; " +高+"]" ; }}

当然龙目像' s @data或@value(取决于您的需求)可能会这样做多年来几年:

所以这些基本上是右边的特征?No.No,他们真的不是。因为对于记录而言,水板减少不是目的,它'只是一个(欢迎)他们的语义的结果。

不幸的是,这很容易丢失。降低水板是显而易见的和性感且易于证明的,所以它得到了很多曝光。但是语义和他们的好处Don' t.it nonn' t帮助那个官方文件还采用了样板角度,而MEP 395更好地解释了语义,由于其范围,由于其范围'在描述下游优势时自然模糊。所以我认为我在这里写下它们。

所以通过创建一个记录你'重新告诉编译器,你的同事,这种类型的整个世界都是关于data的全部世界。恰好,' s(浅)不可变且透明地访问的数据。这是' s核心语义 - 其他一切都从这里遵循。

如果这个语义不适用于你想要创建的类型,那么你应该创建一个记录。如果你做到了一个记录(也许是由没有Butherplate的承诺或者因为你认为记录是等价的到@ data / @value或数据类),you'泥泞的设计和机会很好,它会回来咬你。所以不要' t。

让' s仔细看看透明度。甚至有一个座右铭为此 - 释放项目琥珀色设计文件:

记录模型的API,状态,整个状态,除了状态之外。

具有相同名称和返回类型的每个组件的访问者,该返回返回的组件' s值(或api nonn' t模型状态)

一个可访问的构造函数,其参数列表与组件匹配(称为规范构造函数;或API NON' t模型状态)

没有类继承(或API NON' T模型整个状态,因为更多的状态可以藏在别处))

虽然,为什么?龙目像允许其他字段和kotlin' s数据类以及私人"组件" ('唱片术语; kotlin调用他们的主要构造函数参数)。因此,为什么Java这么严格地对此有所严格?要回答,我们需要一些数学。

一组是一堆元素,例如,我们可以说C是所有颜色的集合{蓝色,金色,。 。 。 n个全自然数{0,1,。 。 。 }。有限集{ - 2147483648,。 。 。 ,0,。 。 。 ,2147483647}是我们在Java中的常常调用int,如果我们抛出null,我们会得到整数。相似的,无限的一组所有可能的字符串(加为null🙄)是我们称之为字符串的。

因此,正如您所看到的,类型是集合' s值的类型,其中' s值正好是该类型合法的值。也意味着设置理论,"研究集的数学逻辑分支&#34 ; (Wikipedia),与类型理论有关,"系统类型&#34的学术研究; (同样),哪种语言设计依赖。

现在让&#39做一些花哨的东西和构建的整数对(是的,那个花哨的):{(0,0),(0,1),。 。 。这是一个简单而非常不完整的Java类,这看起来像:

我们可以调用相应的集合并将其工作。但是,在那里有更多的洞察力,因为我们更了解了关于集合和#39; s结构的更多信息。特殊地,我们知道它的结合'所有INTS都具有所有INTS.SET理论称为产品和IT' S编写为int×int(产品中的每种类型称为操作数)。

' s很酷,因为集合理论有各种各样的事情可以说对这些产品的应用程序。一个方面是如何将在单个操作数上运行的函数组合成在所有操作数上运行的函数以及哪些属性功能(重新注射,黑色等)保持完整。

//给定:来自int到int increment = i - >我== .max_value? .min_value:++ i; //然后:组合两个“增量”生物函数//(这不需要另外的证明或考虑)< > incrementpair =配对 - >新(递增。Applyasint(对。第一()),递增。Applyasint(对。第二()));

您是否注意到了访问者::第一个和::第二个?他们在上面的课堂上没有存在,所以我需要添加它们。又可以向各个组件/操作数应用函数,所以我可以#39; t真的用作一对ints.simarimarly,但在另一个方向上,我需要一个构造函数,将两个ints作为参数占据,所以我可以重新构建一对。

更一般地说,要以我暗示的方式将Set理论应用于一个类型,所以所有操作数都需要访问,并且必须有一种方法可以将操作数量转换为实例。如果两者都是真的,那么类型理论呼叫A型产品类型(及其实例元组),我们可以与它们进行一些很酷的事情。

标称意味着记录由他们的名字而不是它们的结构来标识。您可以' t混合两个不同的记录类型,例如型号×int,例如(int first,int第二)和(int low, INT HIGH).ALSO,我们访问的录制组件不是索引(不是范围。GET1()),但按名称(记录。低())。

(超越该时,记录' S符号和其规范构造函数构成嵌入投影对,但我几乎不明白。虚拟性太少而无法解释。)

我想开车点主页:记录想要是产品类型(因为很酷的东西)和为此工作,所有组件必须可以访问,即可以没有隐藏状态,并且必须从它们的构造。那个'为什么记录是不可变数据的透明载体。

因此,编译器生成访问器。因此,我们可以使用' t更改他们的名字或返回类型。因此,我们应该非常小心地推断它们。因此,编译器生成一个规范构造函数。因此,没有继承。

我们从代数结构获得的大多数好处围绕着乘坐的辅助器与规范构造函数一起允许以结构化的方式分开和重新创建记录实例,而不会丢失信息。

JEP 405提出了记录和阵列模式,这将增强Java和#39; S能力。他们将允许我们分开记录和数组并进一步检查其组件:

if(范围实例(int low,int high)&amp;&amp;高<低)返回新的(高,低);

由于完全透明度,我们可以确定不要错过隐藏状态。这意味着范围和返回的实例之间的区别正是你所看到的:低和高的翻转 - 没有更多。

未来版本的Java可能会使用块介绍,使其非常容易创建(通常是不可变)实例的副本,其中一些值已更改。它可以看出这样的东西:

范围=新(5,10); //语法是组成的! newrange =范围,{low = 0; } //范围:[5; 10] // newrange:[0; 10]

这种语言可以精确地从表达式派生,因为S API与其声明对齐。与之前相似,我们可以依赖于纽约的正常与范围完全相同,除了低电平 - 可以没有隐藏的状态,我们无法运输。真正的语言不得不在这里做多少&#39;

(请注意,此功能远非作为现实,并且可能会掉落或更改。)

将实例旋转到字节流,JSON或XML文档或再次返回任何其他外部表示,需要一种方法将实例分开进入其值,然后拍摄这些值并将它们放在一起。您可以立即查看如何这实际上与Records有关。只有他们只是暴露所有国家并提供规范构造函数,他们以一种结构化方式这样做,使反射API用于非常简单的使用。

有关如何更改序列化的信息,请查看内部Java Podcast,第14集(也可以在许多音频平台上,例如Spotify)。如果您更喜欢简短的阅读,我写了一个关于它的Twitter线程。

返回到第二个水库的第二个。在前面解释,我们需要以下代码,因此记录可以是产品类型:

我没有明确地说明,但它有点很好,如果(0,0)=(0,0),那么欢迎适当的等于实现,它立即需要一个哈希码实现。

由于我们需要所有这些,编译器可能会产生它。所以它确实(并且在ToString中抛出了好的衡量标准) - 没有那么多来拯救我们来写它,而是因为它和#39;是代数结构的自然后果。

记录&#39;语义限制了您可以使用的课程建筑工具。讨论,您可以通过其他字段添加隐藏状态,可以&#39; t重命名访问者,CAN&#39; t更改他们的返回类型,并且可能应该是&#39 ; t更改他们的返回值.Records也不会允许重新分配组件值,即它们的备份字段是最终的,而且没有类继承(尽管如此,您可以实现接口)。

那么如果你需要什么?然后记录aren&#39; t你想要什么,你需要什么,你需要创建一个普通的课程。这意味着只要改变10%的功能,你就会&#39 LL最终有90%的样品板,记录将&#39; ve防止。

Lombok只是生成代码。没有语义附加,所以你拥有所有的自由,你需要适应您的课程.Of and&#39;虽然龙眼洛克斯可能能够在将来产生破坏性方法。

(如此,我说,我不使用Lombok宣传。它很大依赖于编译器内部的API,这可以随时改变,这意味着使用它可以在任何次要Java更新中打破任何次要java更新。隐藏其用户的技术债务也不伟大。)

您经常创建主要目的是保持数据的类。在此类类中,某些标准功能和实用功能通常是从数据机械派生的。

您可以看到持有数据的语义也在那里,但它相当弱,焦点是在推导功能,即生成代码.D数据类提供比记录更多的类建筑工具(可变&#34 ;组件&#34;,隐藏状态,......),但与龙目岛不同,您可以&#39; t使用所有这些(CAN&#39; t延长,CAN&#39; t创建自己的复制方法。 ..)。另一方面,数据类Don&#39; T给记录&#39;强烈的保证,所以kotlin可以在其中的顶部建立相同的功能。

在你把键盘拿出来写作愤怒的评论之前(你可以&#39; t,因为我没有att#39; t&#39; t fat to with-har har),这不是价值判断。&#39; sa不同的贸易 - 脱离不同的成本和福利,如果kotlin&#39;&#39;&#39;很好地与me.don&#39; t @ me(正如孩子们所说的那样)。

所以当然记录aren&#39; t一般比其他两个特征或更差或其他有类似设计的特征,如scala&#39; scase类。但他们确实具有强大的语义,具有坚定的数学基础,同时限制我们的班级设计空间,启用强大的功能,否则无法或至少不可能。

它&#39;在开发人员自由和语言权之间的权衡。它&#39;我的一个&#39;我很高兴,期待看到明年的展示&#39;