当前位置: 首页 > 面试题库 >

可变对象与不可变对象

蓝飞
2023-03-14
问题内容

我正在努力使可变对象与不可变对象有关。使用可变对象会带来很多负面影响(例如,从方法中返回字符串数组),但是我很难理解它的负面影响。使用可变对象的最佳实践是什么?您是否应尽可能避免使用它们?


问题答案:

好吧,这有几个方面。

  1. 没有参考身份的可变对象会在奇数时间导致错误。例如,考虑Person使用基于值的equals方法的bean
Map<Person, String> map = ...
Person p = new Person();
map.put(p, "Hey, there!");

p.setName("Daniel");
map.get(p);       // => null

Person实例用作键时,实例在映射中“丢失”,因为实例hashCode和相等性基于可变值。这些值在映射之外更改,并且所有散列都已过时。理论家喜欢在这一点上竖琴,但实际上,我并没有发现这是一个太大的问题。

  1. 另一方面是代码的逻辑“合理性”。这是一个很难定义的术语,涵盖了从可读性到流程的所有内容。通常,您应该能够查看一段代码并轻松了解其功能。但是比这更重要的是,您应该能够使自己相信它可以正确地完成工作。当对象可以在不同的代码“域”中独立更改时,有时会变得难以掌握位置和原因(“诡异的动作”)。这是一个更难以例证的概念,但是在更大,更复杂的体系结构中经常会遇到这个问题。

  2. 最后,可变对象在并发情况下是致命的。每当您从单独的线程访问可变对象时,都必须处理锁定。这减少了产量,使你的代码大大更难维护。一个足够复杂的系统将这个问题严重地夸大了,以致几乎无法维护(即使对于并发专家而言)。

不变的对象(尤其是不变的集合)避免了所有这些问题。一旦您了解了它们的工作原理,您的代码就会发展为易于阅读,易于维护且不太可能以奇怪和不可预测的方式失败的代码。不可变对象不仅因为其易于模拟性,而且由于它们倾向于强制执行的代码模式而更易于测试。简而言之,它们是一个很好的实践!

话虽如此,我在这件事上并不是狂热者。当所有事物都是不可变的时,有些问题只是无法很好地建模。但是我确实认为您应该尝试朝该方向尽可能多地推送代码,当然,前提是您所使用的语言使这种观点站得住脚(C / C ++和Java一样使这一点非常困难) 。简而言之:优势在某种程度上取决于您的问题,但是我倾向于不变性。



 类似资料:
  • 本文向大家介绍浅谈Python中的可变对象和不可变对象,包括了浅谈Python中的可变对象和不可变对象的使用技巧和注意事项,需要的朋友参考一下 什么是可变/不可变对象 不可变对象,该对象所指向的内存中的值不能被改变。当改变某个变量时候,由于其所指的值不能被改变,相当于把原来的值复制一份后再改变,这会开辟一个新的地址,变量再指向这个新的地址。 可变对象,该对象所指向的内存中的值可以被改变。变量(准确

  • 我想确保我正确理解根据Java内存模型的‘有效不可变对象’行为。 假设我们有一个可变类,我们希望将它发布为一个有效不可变的类: 我们执行以下操作: 问题是:Java内存模型是否保证所有线程必须具有? 根据Java并发实践,这应该是正确的,但如果我错了,请纠正我。 3.5.3.安全发布习语 要安全地发布对象,必须同时使对对象的引用和对象的状态对其他线程可见。通过以下方法可以安全地发布正确构造的对象:

  • 我的目标是让Java对象不可变。我有一个班级< code >学生。为了实现不变性,我用以下方式对它进行了编码: 我的问题是,实现班级不变性的最佳方法是什么?

  • 问题内容: 这是Java Concurrency in Practice中的一句话 共享的只读对象包括不可变的和实际上不可变的对象。 不变对象和有效不变对象之间有什么区别? 问题答案: 不可扩展且其字段全部为自身且不可变的类的实例是不可变的。 由于其方法的详细信息而无法更改其字段的类的实例实际上是不可变的。例如: 的某些实例实际上是不可变的,而有些则不是。 另一个例子是零长度数组。它们实际上是不可

  • 问题内容: String abc[]={“abc”}; String def[]={}; 通过更改“ def”对象,我的abc对象也被更改。在String []数组旁边有这个特性还有什么其他的Java对象有类似的特性?能解释更多吗?为了防止在更改def时更改abc,我必须执行def = abc.clone();。 问题答案: 您将对象的可变性/不可变性与引用值的复制混淆了。 在这些图中,是参考变量

  • 问题内容: 有以下课程: } 它产生以下结果: 由于hashCode取决于对象的状态,因此无法再正确检索它,因此对包含的检查失败。HashSet不再正常工作。一个解决方案是使Member不可变,但这是唯一的解决方案吗?是否所有添加到HashSets的类都是不可变的?还有其他方法可以处理这种情况吗? 问候。 问题答案: 在hashsets对象应该 要么 是不可变的, 或者 你需要锻炼的纪律,他们已经