00:00
下面呢,我们来讲第三个新特性,称为呢叫record,这呢我写了一句话,叫做官方吐槽最为致命。哎,怎么来理解呢?就是当我们说一个新特性所代表的这个问题,想解决的问题呢,官方都开始吐槽了,那他确实是一个确实是一个非常重要的一个问题了,那比如说像现在这个疫情,当前美国总统呢,特朗普发布了很多这个应对疫情的一些措施,也看到了像纽约州的这个州长,以及呢,国内的其他的一些组织呢,不同程度的去这个反对特朗普,或者说呢,批评特朗普的一些政策,这呢就称为叫官方吐槽。那一旦出现这样问题呢,肯定是因为发生了很多的这个很严重的问题了,对吧,那这里呢,就提到这个19年二月份,在我们Java这个语言这个层面,有一个架构师,他呢写过一篇文章,详细的吐槽了Java语言当中的一些太啰嗦,或者说呢,有太多的繁文缛节这样的一些语法问题。这个事的话呢,其实大家呢,也并不是首次听说过,尤其呢是我们有些Java程序员,呃,使用过像Colin使用过skyla使用过呢,像这个Python这样语言之后呢,你会发现由于咱们Java已经几十年的时间了,确实有一些语法呀,没有刚才提到的这样的一些语言呢,更轻巧一些,那我们现在也尽可能希望呢做一些改变,那record这块呢,就可以看成是改变之一。
01:22
说呀,当我们在一个Java程序当中需要创建纯数据载体类的时候,我们呢,通常需要编写像构造函数,像get set的方法,Equals哈和to这样的方法,那么这些方法的话呢,首先说必须要定义对吧,就像我们在定义这个宾扎va宾一样,必须要定义,但是这些方法呢,在我们看来就是大量属于叫低价值的,重复性的,还容易出错的代码。你要自己写的话呢,很容易是不是就写错了呀,那么以至于呢,我们通常呢,是不是在用这个这个这个idea的时候,或者呢,用这个eclipse的时候呢,使用这个自动生成这个功能啊,但是自动生成感觉也是有点麻烦,因为你这个代码整个来看呢,是不是也挺多的呀,那同时的话呢,还会有一些第三方的一些类库啊,这呢就提到叫lobo lobo里边呢,有一个叫data的一个注解,可以呢,就是自动的去生成这样的一些结构,表现出来叫令人吃惊的表现,但是同时呢,有具备这个叫糟糕的可调试性。
02:19
就是优点呢跟缺点呢并存。啊,那么为了呢,咱们减少像这个数据载体类的这个声明,刚才呢,提到的呢,叫longbo这样一个data的注解,包括呢,像Co中的这个data class,以及呢,像skyla语言当中的这个我们叫case class,还有呢,像这个C语言当中这个叫record等等,也都是为了解决这个类生命中的一些这个结构,嗯,这个提供的一些相关的一些措施,那么我们Java的话呢,就在14这个版本当中引入了一个,这呢我们目前还不能叫做关键字啊,只能称为一个叫标识符啊,叫做record,说神说要用record,于是呢就有了,那我们在这个14版本中引入这个新特性以后啊,咱们就能够避免再去定义这个叫数据载体类的时候呢,去显示的声明构造器这个equals highco的to string,这呢,访问器呢,就类似于我们去访问这个属性的get的方法一样,就是这样的一个意思。
03:16
好,那说到这儿的话呢,我们来演示一下,看看到底这个recordcon呢,就神到哪了,就简单到哪了,肯定呢,大家一入手肯定还是非常惊讶的啊行,那首先呢,我们回顾一下啊,我在这个包下呢,咱去定义一个类。这个类呢,不妨我就称为呢,叫做user。那定义这一类的话呢,我把这一类成明成声明成是一个叫final的,就是它不能够被继承了,对吧?那在这里边我们去声明它的这个属性,Private,比如叫final类型,死string型的name final类型,比如叫user类型的,我们称为叫partner,还是它这个类型的这个变量,这两个不能叫变量了,常量我们在构造器当中对它进行赋值,这呢,我就直接是不是应该叫这个线程,这个线程的这个结构了,那么构造器中我们给这两个属性呢,做一个赋值。
04:04
OK,这是构造器,同时的话呢,我们也去给他去提供对应的这个叫盖方法。Set方法不可能了,因为这是两个final的,对吧,只能获取,不能够再重新赋值了,接着的话呢,我们再去提供它这个叫equals和high的方法。这呢,就是咱们通常使用这个IDE当中的这个是不是自动生成这样的功能啊。没问题是吧,哎,我们呢,就是把这两个属性呢,是不是都给它考虑在内分一下。行,然后呢,再加上一个叫to string的这个方法。差不多了,这个事儿呢,大家并不陌生,这呢我就造好了关于这个user类的它的基本的这些结构,我们把它呢就称为一个叫数据载体类,或者呢,我们通常写个扎B是吧,但是扎B这块呢,我们这个相应的这个属性呢,也没有对应的这个赛方法,这个属性呢,我们这里呢,都加加成这个具体的叫final了,对吧。好,这呢就是咱们以前的一种定义方式,那现在同样的这个结构,注意啊,同样的这个结构我呢就可以用更加轻便的方式来定义,大家注意了啊,我直接呢这块去new new一个class,但是此时呢,我选的是record。
05:08
当然了,大家也可以自己呢,你去定一个class,然后改成个record也行,这呢我就直接选这个record,比如我们现在定一个我称为呢叫person,好我一回车。在这里边我们呢,要想想让它实现跟我们这个定义user是同样的效果,只是呢,它这两个名不一样而已啊,我们这呢叫person,好,大家注意别眨眼,我很快呢就写完了。逗号,然后呢,Person类型的我们称为叫partner。写完了。我现在呢,写的这个代码就等同于之前我们写的这些代码。有同学是不是觉得非常不可思议啊,那事实上就是这样,我们使用这个record呢来定义一个类,或者叫生命一个类能够大幅度的减少我们定义类中的这个相关的一些结构。啊,相关的结构行,我说呢,写完了,写完了咱们是不是就可以来测试一下啊,我们在这个FEATURE03这个当中,我们来进行测试,我这块呢,来写这个单元测试方法,好,那来测试,首先呢,咱们来测试一下这个构造器吧。
06:12
有同学可能会想说,我们这哪写构造器了,写了这呢就是构造期,构造器这个参数啊,就是name和partner对应的这个类型啊,都写的很清楚,那意味着就是我们这类里边,其实good这个这个属性啊也是有两个,一个呢叫做name,一个呢就叫做partner,好,那我这块来写声明为叫person,我写一个叫PE new,一个person在这里边呢,我们首先写个姓名,对吧。咱们写一个叫。罗密欧与朱丽叶,罗密欧是男的是吧?罗密欧吧?罗密欧,行,然后呢,他有个partner,这我们再声明一个person在这里边,我们指明这个叫朱丽叶,朱丽叶我写成一个拼音了,然后它这块partner这块我们就暂时先写成个。能理解是吧,这呢是我们就生明了一个,这个创建了一个对象。
07:03
你看呢,这块并没有报错,说明我们这对象呢,是不是真的就创建成功了,那创建成功以后呢,我们试图呢,给它输出一下P,相当于呢,是不是掉了一个to string的方法。那这里我们要看一下这个促进方法输出的是一个地址值吗?不是是吧,那很显然这个结构呢,如果大家呢,有这个经验呢,你肯定知道呢,相当于是不是掉了重写的to string方法了,而我们这个结构当中,你看到是不是根本就没有写呀。就很神奇是吧,这呢,我们来看一下什么呀,看一下源码。不是看源码,看一下自解码是吧,看下自解码就是你现在这个源码呢,就长这样子,那么这个结构我们编以后呢,会生成自解码文件,这个字节码文件呢,并不是我们现在看到这样的简洁的结构了。那大家看这个自己码文件进行一个反编译呢,咱们可以用这个jarp,我这呢就不在这块给大家去演示jarp了,因为咱们这个idea呢,是不是有一个比较强大的功能,它可以直接呢看这个自己码文件,对吧。我们找到咱们当前这个叫mole,找到咱们当前这个结构叫。
08:03
Person在这儿对吧,打开也可以刷新一下啊好,大家来看一下,你是不是感觉非常的惊奇是吧,或者叫惊奇这个person类呢,它本身声明成是个final了,它有一个父类。这是一方面,这个咱们一会再说也行,在这个当中呢,你看他声明了两个属性叫name和partner,也声明成final的类型呢,跟我们这里边声明的这两个类型是一样子的,然后他还给我们提供了一个构造器,这个构造器就俩参数,这俩参数呢,是不是正好跟我们这个结构是特别像啊。就是由这呢来确定了我们这个唯一的构造器是这样子的,然后twoth three high equals都提供好了。那下边呢,还有这个name和partner这两个方法,这两个方法呢,其实类似于咱们这两个属性的get方法,只不过呢,这个名字呢,我没有get,直接呢用这个属性名来进行一个命名。是这样子的啊,那么这些方法呢,咱们就可以在这儿呢,进行一个测试啊。
09:01
刚才呢,咱们这块测试的算是构造器,那这呢是不是就相当于来测试了一下叫to string的方法,其实咱们看到这个反编以后的这个自解码这个信息以后呢,其实已经很清楚了,当然我们也可以给大家再去测试一下啊,接下来我们来这个测试一下这个叫EQ的方法。那我们就可以再拗一个对象,不妨呢,我们就就扭了个他,嗯,往下移。我这儿呢叫P2。其实呢,测试这个事呢,非常简单,我们直接呢就打印一下,然后呢,让P1调了一库方法,我们调下这P2如果呢,你重启了,那此时呢,他俩是不是就是处,那没重启的话就false呗。因为没重写,用的就是我当中的一个方法对吧?哎,就是默认的比较是等等了啊,那这时候是处说明我们是啊,按照这个属性来比较的,这个属性值呢,都是相同的,这呢叫E4还可以呢,咱们来测试。诶,这个没加测试啊。测试E4,咱这呢来测试一下这个叫哈希扣的方法,哈扣的方法呢,如果没有重写,相当于就是一个。
10:07
自动生成的一个哈库的,或者相当于一个随机值一样,那么如果我们重写以后呢,那是不是说像这两个对象,我们把它的属性呢,都参与计算哈库的话呢,算出来值应该是一样子的,对吧?那怎么证明这个事儿呢,直接输出也行,或者呢,我可以这样来做,顺便呢,咱把这ES呢,也可以再做一个验证,我这块呢,去new一个哈希set里边呢,放的就是咱们这个person。Out center生成这个呢,就成为一个叫set了,行,然后呢,我们把刚才呢,咱们造的这两个对象,一个叫P1,一个叫P2呢,给它添加进去,Set呢,大家都用过对吧?我们主要呢使用它来进行这个驱虫的操作,我现在呢,把两个对象都放进去,这两个对象呢,我们按E扣比呢,就是一样子的,那当然呢,这个在添加的时候呢,先要经过一个哈西的判断,如果两个值一样了,E口子一样,实际上呢,就只会留一个。那咱们这块呢,是不是可以去利一下这个,我们可以调这个这块看一下这个结果。
11:08
执行。好,大家看此时呢,咱们这个size当中是不是就只有一个元素啊,那就相当于我们第一个添加进去以后,第二个呢就没有进去呗,所以这呢,其实就在这个过程当中调用了这个哈Co的,其实呢,以及呢也会调用咱们这个ES,具体的这个添加的细节是不是也是一个常见的面试题,叫哈希map的底层实现原理,对吧?这呢我们就不讲了,不是咱们这块涉及到这个问题啊,这个大家在面试当中呢,常还问到一个问题,这就咱们就过了。还有什么特性呢?咱们还对应的是不是有它这个叫name的这个方法和这个叫partner。这两个方法,这两个方法呢,其实我们说呀,叫类似于。咱们原来你像有name属性和partner属性的话呢,就是相当于叫get name和叫get partner。
12:05
就成这样了啊是这个意思,那咱们这块呢,CTRLC一下,把这两咱们也做一个测试,我直接呢就做输出了,通过这个P咱们调这个方法,调了个partner这个方法。那你要调这个PE的话呢,就是内叫罗密欧,它的这个partner呢,就是我们这个叫朱丽叶对吧。行出来了,这呢就是罗密欧,这呢是它的partner,行这呢我们就相当于是把这个结构呢,是不是整个来测试了一下。大家会发现就是这个结构写法呢,还真是够简洁的啊。这是呢,它的一个基本使用,咱们呢就先说到这儿啊。
我来说两句