Java编程学习之java的不可变数据结构.docVIP

Java编程学习之java的不可变数据结构.doc

  1. 1、本文档共8页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  5. 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  6. 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  7. 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  8. 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多

Java编程学习之java的不可变数据结构

//Addressisvalidanddoesn’thavesetters,sotheaddressobjectisalwaysvalid.

线程安全

由于无法更改对象,因此可以在线程之间共享它,而不会出现竞争条件或数据突变问题。

易于理解的代码

与无效状态的代码示例类似,使用构造函数通常比初始化方法更容易。这是因为构造函数强制执行必需的参数,而setter或initializer方法在编译时不会强制执行。

更易于测试的代码

由于对象更具可预测性,因此不必测试初始化??方法的所有排列,即在调用类的构造函数时,该对象有效或无效。使用这些类的代码的其他部分变得更可预测,具有更少的NullPointerException机会。有时,当传递对象时,有些方法可能会改变对象的状态。例如:

publicbooleanisOverseas(Addressaddress){

if(address.getCountry().equals(Australia)==false){

address.setOverseas(true);//addresshasnowbeenmutated!

returntrue;

}else{

returnfalse;

}

}

一般来说,上面的代码是不好的做法。它返回一个布尔值,并可能改变对象的状态。这使得代码更难理解和测试。更好的解决方案是从Address类中删除setter,并通过测试国家名称返回一个布尔值。更好的方法是将此逻辑移动到Address类本身(address.isOverseas())。当确实需要设置状态时,在不改变输入的情况下制作原始对象的副本。

可用于值类型

想象一下金额,比如10美元。10美元将永远是10美元。在代码中,这可能看起来像publicMoney(finalBigIntegeramount,finalCurrencycurrency)。正如您在此代码中看到的那样,不可能将10美元的值更改为除此之外的任何值,因此,上述内容可以安全地用于值类型。

最终引用不要使对象不可变

如前所述,我经常遇到的问题之一是这些开发人员中的很大一部分并不完全理解最终引用和不可变对象之间的区别。似乎这些开发人员的共同理解是,变量成为最终的那一刻,数据结构变得不可变。不幸的是,这并不是那么简单,我想一劳永逸地把这种误解带出世界:

Afinalreferencedoesnotmakeyourobjectsimmutable!

换句话说,下面的代码并没有使对象不变:

finalPersonperson=newPerson(John);

为什么不?好吧,虽然person是最后一个字段而且无法重新分配,但是Person类可能有一个setter方法或其他mutator方法,可以执行如下操作:

person.setName(Cindy);

无论最终修饰符如何,这都是一件非常容易的事情。或者,Person类可能会公开这样的地址列表。访问此列表允许您向其添加地址,因此,如下所示改变person对象:

person.getAddresses().add(newAddress(Sydney));

好了,既然我们已经解决了这个问题,那么让我们深入了解一下我们如何使类不可变。在设计我们的类时,我们需要记住几件事:

不要以可变的方式暴露内部状态

不要在内部改变状态

确保子类不会覆盖上述行为

根据以下准则,让我们设计一个更好的Personclass版本。

publicfinalclassPerson{//finalclass,can’tbeoverriddenbysubclasses

privatefinalStringname;//finalforsafepublicationinmultithreadedapplications

privatefinalListAddressaddresses;

publicPerson(Stringname,ListAddressaddresses){

this.name=name;

this.addresses=List.copyOf(addresses);//makesacopyofthelisttoprotectfromoutsidemutations(Java10+).

//Otherwise,useCollections.unmodifiableList(newArrayList(addresses

文档评论(0)

158****9567 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档