前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Immutable和final

Immutable和final

作者头像
凯哥的Java技术活
发布2022-07-08 14:16:05
4970
发布2022-07-08 14:16:05
举报

定义

Immutable --- 不可变

final --- java final关键字

关于final关键字有一点思考。就像最近在思考的另一句话:不能听命自己者,必将受制于他人!

可变与不可变

在final关键字上出现了点理解上的问题,不知道这玩意什么时候用。

在翻阅一部分代码的时候,经常发现某几个对象,有几十个上百个属性,每个属性都是一个get set方法。然后这个对象出现在很多上下文中,导致你根本不知道某个属性是哪里设置的。最极端的是一个万能的类,包含了N多个属性和N多个方法,导致这个对象成为了”God Object“,无所不能的上帝对象,降低了维护性。

除了拆解为独立的对象外,在想是否需要不可变对象?也就是标题的Immutable?

不可变对象的好处。容易解释,状态在一经创建就无法修改,我们可以在创建的时候顺便校验下,那么该对象在其生命周期内都是合法的属性。另外在并发编程时有优势,因为不可变,多线程都是读的同一份数据,不用担心某个人不小心修改了它。

不可变对象的坏处。麻烦。会损耗点性能,因为在必要的时候需要copy对象,难免会牺牲点性能。另外确实它比较麻烦,比如在json序列化的时候,用jackson的话需要写@JsonCreator,每个属性都要标记一下。

如何写一个不可变对象

如何写一个Inmutable对象?这个给出一个简单的规则。

1、永远不要提供"setter"方法,

2、所有的字段都是final和private的

3、不要让子类重写方法,最简单的是声明为final

4、如果包含了可变对象的引用

4.1、不要暴露这个引用

4.2、不要提供修改这个可变对象的方法

代码逻辑

代码的逻辑“合理性”。这是一个很难定义的术语,涵盖了从可读性到流的所有方面。当对象可以在不同的代码“域”之间独立更改时,有时很难跟踪什么是在哪里以及为什么(“远处的诡异行为”)。这是一个更难举例说明的概念,但在更大、更复杂的体系结构中经常会遇到这种情况。

在并发情况下,可变对象是致命的。无论何时从不同的线程访问可变对象,都必须处理锁定问题。这会降低吞吐量,并使代码更难维护。一个足够复杂的系统将这个问题处理得如此严重,以至于几乎无法维护(即使对于并发专家来说)。

成熟的代码是如何选择的?

关于可变对象与不可变对象的两大阵营,一类认为没必要,一类则是不可变对象的狂热分子。

为了看清楚不可变和可变,在目前很成熟的代码中寻找一些影子。

首先是Spring,在Spring Security中,不可变和可变对象都比较多,例如Authentication在系统中就是不可变的,这其实也说得通,一旦被认证过,后续这个身份就不应该再改变了。但是大多数都是可变对象,比较灵活。

Scala中的集合默认都是不可变的,Scala 集合类系统地区分了可变的和不可变的集合。可变集合可以在适当的地方被更新或扩展。这意味着你可以修改,添加,移除一个集合的元素。而不可变集合类,相比之下,永远不会改变。不过,你仍然可以模拟添加,移除或更新操作。但是这些操作将在每一种情况下都返回一个新的集合,同时使原来的集合不发生改变。

之前会好奇scala为何如此多此一举?貌似java中都是可变的,可以随意的add remove操作。但是为何scala的作者如此设计,也是为了考虑immutable的重要性吧,毕竟scala也可以成为java++的。虽然用得少,不代表不厉害,scala语言太过于灵活可能也是使用者相对较少的原因之一。但是大量的在框架的底层使用着,例如spark和kafka,都是很多scala的代码。语法过于风骚,这里不说了。

为啥没人用不可变对象?

为啥大家都不用不可变对象呢?

看到最令人信服的原因是:因为大家可变编程持续了这么久了,懒的动。

可能很多人不热衷于不可变这件事。但是这也不妨碍停下来思考下,在系统的某个角落,可能这样更合适。

我认为,尽量多使用不可变对象,这样有助于减少复杂系统的可变性,让变量少到你能够掌握!

最后,用kafka对代码的要求结束这篇文档。

  • Use final when possible. This holds for all class members, local variables, loop variables, and method parameters.

尽量使用final,这样可减少系统中的可变性。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-05-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 凯哥的Java技术活 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档