免费预览已结束,剩余1页可下载查看
下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
作为我最近一直在进行的一些编码访谈的一部分,有时会出现不变性问题。我自己并不过分教条,但每当不需要可变状态时,我会试图摆脱导致可变性的代码,这在数据结构中通常是最明显的。然而,似乎对不可变性的概念存在一些误解,开发人员通常认为拥有final引用,或者val在Kotlin或Scala中,足以使对象不可变。这篇博客文章深入研究了不可变引用和不可变数据结构。不可变数据结构的好处不可变数据结构具有显着优势,例如: 没有无效的状态 线程安全 易于理解的代码 更容易测试代码 可用于值类型没有无效的状态当一个对象是不可变的时,很难让对象处于无效状态。该对象只能通过其构造函数实例化,这将强制对象的有效性。这样,可以强制执行有效状态所需的参数。一个例子:Address address = new Address();address.setCity(Sydney);/ address is in invalid state now, since the country hasnt been set.Address address = new Address(Sydney, Australia);/ Address is valid and doesnt have setters, so the address object is always valid.线程安全由于无法更改对象,因此可以在线程之间共享它,而不会出现竞争条件或数据突变问题。易于理解的代码与无效状态的代码示例类似,使用构造函数通常比初始化方法更容易。这是因为构造函数强制执行必需的参数,而setter或initializer方法在编译时不会强制执行。更易于测试的代码由于对象更具可预测性,因此不必测试初始化方法的所有排列,即在调用类的构造函数时,该对象有效或无效。使用这些类的代码的其他部分变得更可预测,具有更少的NullPointerException 机会。有时,当传递对象时,有些方法可能会改变对象的状态。例如:public boolean isOverseas(Address address) if(address.getCountry().equals(Australia) = false) address.setOverseas(true); / address has now been mutated! return true; else return false; 一般来说,上面的代码是不好的做法。它返回一个布尔值,并可能改变对象的状态。这使得代码更难理解和测试。更好的解决方案是从Address 类中删除setter ,并通过测试国家名称返回一个布尔值。更好的方法是将此逻辑移动到 Address 类本身(address.isOverseas())。当确实需要设置状态时,在不改变输入的情况下制作原始对象的副本。可用于值类型想象一下金额,比如10美元。10美元将永远是10美元。在代码中,这可能看起来像 public Money(final BigInteger amount, final Currency currency)。正如您在此代码中看到的那样,不可能将10美元的值更改为除此之外的任何值,因此,上述内容可以安全地用于值类型。最终引用不要使对象不可变如前所述,我经常遇到的问题之一是这些开发人员中的很大一部分并不完全理解最终引用和不可变对象之间的区别。似乎这些开发人员的共同理解是,变量成为最终的那一刻,数据结构变得不可变。不幸的是,这并不是那么简单,我想一劳永逸地把这种误解带出世界:A final reference does not make your objects immutable!换句话说,下面的代码并没有使对象不变:final Person person = new Person(John);为什么不?好吧,虽然person是最后一个字段而且无法重新分配,但是 Person类可能有一个setter方法或其他mutator方法,可以执行如下操作:person.setName(Cindy);无论最终修饰符如何,这都是一件非常容易的事情。或者, Person类可能会公开这样的地址列表。访问此列表允许您向其添加地址,因此,如下所示改变 person对象:person.getAddresses().add(new Address(Sydney);好了,既然我们已经解决了这个问题,那么让我们深入了解一下我们如何使类不可变。在设计我们的类时,我们需要记住几件事: 不要以可变的方式暴露内部状态 不要在内部改变状态 确保子类不会覆盖上述行为根据以下准则,让我们设计一个更好的Person class 版本 。public final class Person / final class, cant be overridden by subclasses private final String name; / final for safe publication in multithreaded applications private final List addresses; public Person(String name, List addresses) = name; this.addresses = List.copyOf(addresses); / makes a copy of the list to protect from outside mutations (Java 10+). / Otherwise, use Collections.unmodifiableList(new ArrayList(addresses); public String getName() return ; / String is immutable, okay to expose public List getAddresses() return addresses; / Address list is immutable public final class Address / final class, cant be overridden by subclasses private final String city; / only immutable classes private final String country; public Address(String city, String country) this.city = city; this.country = country; public String getCity() return city; public String getCountry() return country; 现在,可以使用以下代码:import java.util.List;final Person person = new Person(John, List.of(new Address(“Sydney”, Australia);现在,上面的代码是不可变的,但是由于Person 和 Address 类的设计 ,同时还有最终引用,因此无法将person变量重新分配给其他任何东西。更新:正如有些人提到的,上面的代码仍然是可变的,因为我没有在构造函数中复制地址列表。因此,如果不在ArrayList() 构造函数中调用new ,仍然可以执行以下操作:final List addresses = new ArrayList();addre
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 学生建议书15篇
- 小学语文学习计划集锦四篇
- 2021个人军训后心得感想总结九篇
- 六年级语文上册 第一单元 习作:变形记教学实录 新人教版
- 关于开业庆典策划方案范文5篇
- 关于庆祝教师节2021活动方案策划
- 产品营销方案策划锦集五篇
- 餐饮十年工作感悟心得7篇
- (水滴系列)七年级地理上册 第五章 第3节 聚落 人类的聚居地教学实录 (新版)商务星球版
- 黑龙江省青冈县兴华镇中学九年级化学下册 生活中常见的盐-食盐教学实录 沪教版
- 广东省珠海市2023-2024学年高二上学期语文期中试卷(含答案)
- 民事诉讼法试题库
- 山东省济南市2023-2024学年高一上学期1月期末考试数学试题 含解析
- GB/T 44317-2024热塑性塑料内衬油管
- 七年级道德与法治期末复习计划范文两篇
- 营养与食品卫生学智慧树知到答案2024年温州医科大学
- 艺人直播带货合同(坑位费-CPS)
- 2024-2025学年高中英语学业水平合格性考试模拟测试卷六含解析
- 创伤失血性休克中国急诊专家共识2023解读课件
- GB/T 44180-2024厨卫五金产品通用技术要求
- 教师如何撰写教研论文
评论
0/150
提交评论