专注于Java领域优质技术,欢迎关注
原文地址:why null is bad跳转中...原文作者:Yegor Bugayenko译者:高老庄里的猿先来看个 Java 中使用 null 作为返回值的简单例子:
该方法最大的问题是返回 null 代替了对象。在面向对象规范中使用 null 是个非常糟糕的做法,应该极力避免。有很多论据可以支持这一观点,包括 Tony Hoare 的演讲《Null References, The Billion Dollar Mistake》和 David West 的《Object Thinking》 整本书。接下来我将所有的论据做一些整理并使用合适的面向对象结构代替 null 作为返回值。目前看来,至少有两种方法可以代替使用 null 。
1、使用空对象设计模式(最好定义一个常量)
2、当不能返回一个对象时,可以抛出异常来让调用方 fail-fast(快速失败)
现在来看看反对使用 null 的依据,除了上面提到的 Tony Hoares 的演讲和 David West 的书籍,还有 Robert Martin 的 《Clean Code》、 Steve McConnell 的《Code Complete》、John Sonmez 的 《Say “No” to “Null”》以及 StackOverflow 上的讨论《Is returning null bad design? 》,这些我在写这篇文章之前都看过。
特殊错误处理每次将对象引用作为输入时都必须检查它是 null 的还是有效的,如果忘了检查,将会导致运行时 NPE(Null Pointer Exception)。因此,你的代码逻辑会被多种检查和 if/then/else 分支所污染。看看下面例子:
这是 c 语言和其他很多面向过程编程语言处理异常所使用的方法,面向对象编程引入异常处理主要就是为了消除这些特殊的错误处理逻辑。在面向对象编程中,我们将异常以冒泡的方式不断的向上抛出直到应用层,这样我们的代码将变得更加小而美。
dept.getByName("Jeffrey").transferTo(dept2);
null 是面向过程编程的"封建余孽",请使用 null 对象或者异常代替之。
语义的二义性为了显示的将"函数会返回真实的对象或者 null "这层含义表达出来,getByName() 必须命名为getByNameOrNullIfNotFound()。每个类似的函数都应该这样做,否则会给代码阅读者来带来歧义。
为了语义的准确性,你应该为函数定义更长的名称。
为了消除歧义,函数尽量返回一个真实的对象、一个 null 对象或者抛出一个异常。
有些人会争辩说有时为了性能,不得不返回 null。比如 java Map 接口中的 get() 方法,当在 map 中找不到相应的条目时会返回 null,例如:
由于 Map 的 get() 方法返回 null ,上面代码只会在 map 中搜索一次。如果我们想重写 Map 的 get() 方法以让其在查找不到条目时抛出异常,代码应该这样写:
很明显,这个方法比第一个方法慢两倍,怎么办呢? 我觉得 Map 的接口设计存在缺陷(无意冒犯作者),它应该返回一个迭代器 Iterator 以便让我们代码可以像如下这样:
BTW,这正是 C 标准库(STL)中 map::find() 方法的设计思路。
计算机思维 vs 对象思维假如某人知道 Java 对象是一个指向某个数据结构的指针,并且 知道 null 是一个空指针(在英特尔 x86 处理器中等于 0x00000000),那他应该能接收 if(employee == null) 这个语句。但是,如果以对象思维来进行思考,这个语句就没意义了。 从一个对象的角度来看,我们的代码是这样的:
Hello, 请问是软件部吗?是的。麻烦让我和你们的 employee(员工) Jeffrey 聊聊。请稍等...Hello你是 NULL ?上面对话的最后一句看起来很奇怪,不是吗? 相反,如果他们在接到我想与 Jeffrey 进行通话的需求后直接挂断电话会快速给我们制造个故障(异常)。这时我们可以尝试着再次拨过去或者直接告诉我们的主管无法联系到 Jeffrey 来完成更大的交易。
或者,他们可以让我们与另一个人交谈,他不是 Jeffrey,但如果我们需要“特定的” Jeffrey(null 对象)的话,他可以帮助我们解决大多数问题,也可以拒绝帮忙。
Slow Failing(慢失败)与 failing fast(快速失败)相反,上述代码尝试缓慢死亡并杀死其他人。它向调用者隐藏了失败而不是让其知道出了问题需要马上进行异常处理。这个结论与上面"特殊错误处理"章节的讨论很接近。最好让代码尽可能脆弱,必要时让它崩溃。
要确保你的方法对调用方提供的操作数有着极高的要求,如果调用方提供的数据不够或者根本不符合方法主要的使用场景,抛出异常吧。或者返回一个 null 对象,该对象暴露一些常见行为,并对所有其他调用抛出异常,参考如下:
可变的和不完整的对象
一般来说,强烈建议在设计对象时考虑到不变性。这意味着对象在实例化过程中获得所有必要的内容,并且在整个生命周期中永远不会更改其状态。 null 通常被用在延迟加载中以使对象不完整且可变。例如:
这种技术虽然应用广泛,但在面向对象编程中是一种反设计模式的。主要是因为它使一个对象负责计算平台的性能问题,而这对 Employee 对象应该是透明的。
与其管理状态并公开业务相关的行为,不如让对象处理好其自身结果的缓存---这就是延迟加载的目的。缓存不是 employee 该在办公室里做的事,不是吗?
解决办法是不要像上面的例子那样,以这种原始的方式使用延迟加载。相反,将这个缓存问题移到应用程序的另一层。例如在 Java中可以使用面向切面编程技术。 例如,jcabi-aspects 使用 @Cacheable 注解来缓存方法返回的值:
希望通过这篇文章的分析,能让你停止在代码中继续使用 null 作为返回值。
来源:掘金 链接:https://juejin.im/post/5d740e7f5188251325775966
半路翻译有效吗(译为什么null)
2024-11-06 02:16:55 作者:的纪念 网址:https://m.xinb2b.cn/tech/aig299963.html
- 奇瑞tj1预计售价(奇瑞T1EJ四驱版实车首曝)
- 2024-11-06奇瑞T1EJ四驱版实车首曝之前写T1EJ的时候顺嘴提及过一个问题,既然此前拍摄的测试车标准两驱版的字眼,是不是意味着该车还有四驱版?何况与星途追风、瑞虎7Plus共享平台的车型,后两者都出现了四驱版的相关信息和实车谍照的情况下。
- 内镜下黏膜切除术有影响吗(什么是内镜下黏膜切除术)
- 2024-11-06什么是内镜下黏膜切除术内镜下黏膜切除,是指于病灶的黏膜下层内注射药物形成液体垫后切取大块黏膜组织的方法,其优点是能增加切除的面积和深度,达到根治的目的,主要适用于部分无蒂息肉、具体情况一起来听听咱们肿瘤大专家的讲解吧内镜黏。
- 名爵mg mulan正式上市12.98万起售(采用CTP技术520KM续航起售12.98万)
- 2024-11-06采用CTP技术520KM续航起售12.98万上汽名爵MGMULAN2022款正式上线上汽名爵MULAN2022款,9月份已经是正式上线,对于这台后驱纯电版本的两厢车,到底怎么样,我们来详细看一看,这款车型上市之后能不能火?全新款的名爵MULAN。
- 年度十大港产片票房排行榜(港影最后的巨星)
- 2024-11-06港影最后的巨星在文字中证道——唐泪唯票房论是一个屡见不鲜的舆论现象就事实来讲,票房是商业价值的外化,演员只要卖座,就会资源如涌香港影史上的巨星,盛名之下,都可以理解为票房之功无论是九十年代的双周一成、五大巨星还是现。
- 江南百景图又见桃花村地下宝库怎么去(进江南百景图又见桃花村地下宝库方法介绍)
- 2024-11-06进江南百景图又见桃花村地下宝库方法介绍在应天府打开【同乡会馆】进入桃花村点击靠近建设村左侧的【地下宝库】图标用一把钥匙打开【地下宝库入口】成功进入到地下宝库,点击【宝箱】用【宝库钥匙】打开沈万三的宝箱获得补天石和金华火腿各位知府大人,记得。
- 安加上一个偏旁变成新的字 再组词
- 2024-11-06安加上一个偏旁变成新的字 再组词中国汉字可谓博大精深,添一笔或去一笔都会变成另外一个新字,这个安全的安加提手旁是按,按兵不动加木字底是案,方案加革字旁是鞍,马鞍山加金字旁是铵,硫酸铵,等等。
- dnf女鬼剑宠物哪个好看(dnf女鬼剑宠物推荐)
- 2024-11-06dnf女鬼剑宠物推荐5月底心悦宠物调整,美名其曰为“新款”,却换汤不换药,多年前曾经出过,老玩家记忆犹新部分宠物时间久远,才“入坑”的玩家,外观一知半解心悦宠物上架短短3天。
- 神舟精盾u65a青春版怎么样(静下心聊聊神舟精盾U系列笔记本是否物有所值)
- 2024-11-06静下心聊聊神舟精盾U系列笔记本是否物有所值不少小伙伴们爱吃鸡,那就是享受站得最稳,笑到最后的乐趣然而要今晚吃鸡,可不是随便都能做到,只凭运气和忽悠人的精神更不能做到神舟全新的精盾U系列发布,便是给行业带来无尽的震撼感其再一次突破了性价。
- 魏延为什么会被人杀(魏延大喊谁敢杀我)
- 2024-11-06魏延大喊谁敢杀我三国时代,豪杰辈出,其中往事,尽付笑谈魏延可谓三国时期极具争议的人物,他的“子午谷奇谋”和“谋反被杀”,被人们议论了千年今天,我们就来聊聊后面这一件,也就是诸葛亮病逝于五丈原后,所发生的事情“爆冷”当。
- 怎么练道家罡气(道家修真学乌龟)
- 2024-11-06道家修真学乌龟几年前,网传台湾明星吴宗宪(JackyWu)修炼“龟息功”睡30分钟抵8小时,不知是真是假?金庸笔下,王重阳仙逝之时,为防止西毒欧阳锋盗取《九阴真经》,好像也用的是“鬼息功”憋了一口气,可见这龟息大法。
- 东莞高温天气时间(关注高温天气大热天)
- 2024-11-06关注高温天气大热天来源:东莞时间网-i东莞女士们穿着清凉,手里拎着刚买的冷饮摄于国贸城附近手里的小风扇,跟这个夏天很搭摄于市民服务中心公交站“全副武装”迎战酷暑摄于壹号广场附近高温,闷热!又到了一年中最热的酷暑时节了昨。
- 怎么替祖国庆生(祖国请点名)
- 2024-11-06祖国请点名炊事员精心制作午餐野外集训炊事员精心制作饭菜我是炊事员,每天早晨四点半,我都会随铃声一起迎接旭日晨曦,洗菜、炒菜、烹饪……看似单调简单的工作,却是我最自豪的时刻,保障好战友的胃,就是保障好战斗力生成我。