日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

为什么NULL是错误的?

發布時間:2023/12/3 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 为什么NULL是错误的? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Java中NULL用法的簡單示例:

public Employee getByName(String name) {int id = database.find(name);if (id == 0) {return null;}return new Employee(id); }

這種方法有什么問題?

它可能返回NULL而不是對象-這是錯誤的。 在面向對象的范例中, NULL是一種可怕的做法,應不惜一切代價避免使用NULL 。 關于此出版物已經有很多意見,包括“ 空引用”, Tony Hoare撰寫的《十億美元的錯誤》演講和David West撰寫的整本《 Object Thinking 》。

在這里,我將嘗試總結所有參數,并舉例說明如何避免使用NULL并使用適當的面向對象的結構代替它們。

基本上,可以使用NULL兩種替代方法。

第一個是Null Object設計模式(最好的方法是使其成為常數):

public Employee getByName(String name) {int id = database.find(name);if (id == 0) {return Employee.NOBODY;}return Employee(id); }

第二種可能的替代方法是在無法返回對象時拋出異常 ,從而快速失敗 :

public Employee getByName(String name) {int id = database.find(name);if (id == 0) {throw new EmployeeNotFoundException(name);}return Employee(id); }

現在,讓我們看看反對NULL的參數。

除了上面提到的Tony Hoare的演示文稿和David West的書以外,我在寫這篇文章之前還閱讀了這些出版物:Robert Martin的Clean Code ,Steve McConnell的Code Complete ,John Sonmez的“ No”到“ Null” , 是否返回無效的不良設計? StackOverflow上的討論。

臨時錯誤處理

每次獲取對象作為輸入時,都必須檢查它是否為NULL或有效的對象引用。 如果忘記檢查,則NullPointerException (NPE)可能會在運行時中斷執行。 因此,您的邏輯將受到多次檢查以及if / then / else分支的污染:

// this is a terrible design, don't reuse Employee employee = dept.getByName("Jeffrey"); if (employee == null) {System.out.println("can't find an employee");System.exit(-1); } else {employee.transferTo(dept2); }

這就是應該用C和其他命令式程序語言處理異常情況的方式。 OOP引入了異常處理,主要是為了擺脫這些臨時的錯誤處理塊。 在OOP中,我們讓異常冒泡直到它們到達應用程序范圍的錯誤處理程序,并且我們的代碼變得更加簡潔明了:

dept.getByName("Jeffrey").transferTo(dept2);

考慮NULL引用是過程編程的繼承,請改用1)Null對象或2)異常。

模棱兩可的語義

為了明確傳達其含義,必須將函數getByName()命名為getByNameOrNullIfNotFound() 。 每個返回對象或NULL函數都應該發生同樣的情況。 否則,對于代碼閱讀器來說,模棱兩可是不可避免的。 因此,為了保持語義的明確性,應為函數指定更長的名稱。

要擺脫這種歧義,請始終返回真實對象,空對象或引發異常。

有人可能會爭辯說,為了性能起見,我們有時必須返回NULL 。 例如,當地圖中沒有這樣的項目時,Java中接口Map get()方法將返回NULL :

Employee employee = employees.get("Jeffrey"); if (employee == null) {throw new EmployeeNotFoundException(); } return employee;

由于Map使用NULL ,因此此代碼僅搜索一次Map 。 如果我們將Map重構,以便其方法get()在未找到任何內容的情況下將引發異常,則我們的代碼將如下所示:

if (!employees.containsKey("Jeffrey")) { // first searchthrow new EmployeeNotFoundException(); } return employees.get("Jeffrey"); // second search

顯然,此方法的速度是第一個方法的兩倍。 該怎么辦?

Map界面(對其作者沒有冒犯)具有設計缺陷。 它的方法get()應該一直返回一個Iterator以便我們的代碼如下所示:

Iterator found = Map.search("Jeffrey"); if (!found.hasNext()) {throw new EmployeeNotFoundException(); } return found.next();

順便說一句,這正是C ++ STL map :: find()方法的設計方式。

計算機思維與對象思維

有人知道Java中的對象是指向數據結構的指針,而NULL是指向0x00000000的指針(在Intel x86處理器中為0x00000000 if (employee == null)可以理解if (employee == null)語句。

但是,如果您開始以對象為對象進行思考,那么這種說法就沒有意義了。 這是從對象角度看我們的代碼的樣子:

- Hello, is it a software department? - Yes. - Let me talk to your employee "Jeffrey" please. - Hold the line please... - Hello. - Are you NULL?

對話中的最后一個問題聽起來很奇怪,不是嗎?

相反,如果他們在我們請求與Jeffrey通話后掛斷電話,這會給我們造成麻煩(異常)。 此時,我們嘗試再次致電或通知主管,我們無法聯系Jeffrey并完成更大的交易。

或者,他們可以讓我們與不是Jeffrey的其他人交談,但是可以幫助我們解決大多數問題,或者在我們需要“特定于Jeffrey”的東西時拒絕幫助(空對象)。

緩慢失敗

上面的代碼沒有快速失敗 ,而是嘗試緩慢消失,從而殺死了其他人。 它沒有讓所有人都知道出了什么問題并且應該立即開始異常處理,而是向客戶端隱藏了此故障。

該參數與上面討論的“臨時錯誤處理”非常接近。

最好使代碼盡可能脆弱,并在必要時讓代碼中斷。

使您的方法對它們操作的數據極為苛刻。 如果提供的數據不足或根本不適合該方法的主要使用場景,請讓他們通過引發異常來進行抱怨。

否則,返回一個Null對象,該對象暴露一些常見行為,并在所有其他調用上引發異常:

public Employee getByName(String name) {int id = database.find(name);Employee employee;if (id == 0) {employee = new Employee() {@Overridepublic String name() {return "anonymous";}@Overridepublic void transferTo(Department dept) {throw new AnonymousEmployeeException("I can't be transferred, I'm anonymous");}};} else {employee = Employee(id);}return employee; }

可變和不完整的對象

通常, 強烈建議設計時牢記不變性的對象。 這意味著對象在實例化過程中會獲得所有必需的知識,并且在整個生命周期中都不會改變其狀態。

通常,在延遲加載中使用NULL值,以使對象不完整且可變。 例如:

public class Department {private Employee found = null;public synchronized Employee manager() {if (this.found == null) {this.found = new Employee("Jeffrey");}return this.found;} }

該技術盡管被廣泛使用,但卻是OOP中的反模式。 主要是因為它使對象負責計算平臺的性能問題,而這是Employee對象不應該意識到的。

對象不必管理狀態并公開其與業務相關的行為,而必須處理其自身結果的緩存-這就是延遲加載的意義所在。

緩存不是員工在辦公室里做的事情,對嗎?

解決方案? 請勿以上述原始方式使用延遲加載。 相反,請將此緩存問題移至應用程序的另一層。

例如,在Java中,您可以使用面向方面的編程方面。 例如, jcabi-aspects具有@Cacheable批注,用于緩存方法返回的值:

import com.jcabi.aspects.Cacheable; public class Department {@Cacheable(forever = true)public Employee manager() {return new Employee("Jacky Brown");} }

我希望這種分析令人信服,您將停止NULL您的代碼!

相關文章

您可能還會發現以下有趣的帖子:

  • Java代碼中的典型錯誤
  • 實用程序類的OOP替代
  • 避免字符串串聯
  • 對象應該是不可變的

翻譯自: https://www.javacodegeeks.com/2014/09/why-null-is-bad.html

總結

以上是生活随笔為你收集整理的为什么NULL是错误的?的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 竹菊影视日韩一区二区 | 小毛片 | 视频一二三区 | 天天躁日日躁狠狠躁伊人 | 国产黄色精品视频 | 国产片久久| 日本两性视频 | 老子影院午夜伦不卡大全 | 国产视频在线一区 | 三级在线观看 | 成人av高清在线 | 亚洲播播 | 亚洲成人精品在线播放 | 国产黄色自拍视频 | 午夜激情视频在线观看 | 爱爱视频网站免费 | 欧美日韩国内 | 曰曰操| 成人三区| 欧美综合自拍 | 麻豆高清视频 | 亚洲国产精品人人爽夜夜爽 | 处破女av一区二区 | 亚洲欧美一区二区三区情侣bbw | 日本黄页网站 | 日韩一级影片 | 亚洲国产精品久 | 精品国产一区二区在线观看 | 欲求不满在线小早川怜子 | 青娱乐久久 | 久久影业 | 亚洲一区视频网站 | 国产精品第二十页 | av在线免播放器 | 被扒开腿一边憋尿一边惩罚 | 日韩欧美片 | 亚洲成人欧美 | 日本两性视频 | 亚洲美女综合网 | 亚洲激情区 | 国产日日操 | 蜜桃视频无码区在线观看 | 小视频国产 | 懂色av中文一区二区三区天美 | 国产a√精品区二区三区四区 | 欧美色图在线观看 | 新天堂在线| 国产喷白浆一区二区三区 | 超碰中文字幕 | 二区在线播放 | 欧洲亚洲综合 | 天堂资源中文 | 国产 日韩 欧美 制服丝袜 | 操比视频网站 | 一区二区三区日韩在线 | 亚洲欧美日韩动漫 | 高清一区二区 | 欧美专区视频 | 亚洲国产综合在线 | 女王人厕视频2ⅴk | 未满十八岁勿进 | 亚洲免费视频一区二区三区 | 狠狠干狠狠艹 | 裸体黄色片 | 欧美乱大交xxxxx潮喷l头像 | 又白又嫩毛又多15p 超碰在线一区 | 国产原创剧情av | 成人污污视频在线观看 | 亚洲性欧美 | 少妇特黄一区二区 | 日韩成人在线播放 | 欧美激情成人在线 | 欧美巨大荫蒂茸毛毛人妖 | 国产乱码精品一区二区三区五月婷 | 手机看片日韩久久 | 中文视频一区二区 | 欧美图片一区 | 黄网站免费观看 | 国产一级片免费视频 | 日韩性欧美 | 国产情侣酒店自拍 | 欧美第二页 | 成人免费三级 | 99国产精品人妻噜啊噜 | 精品无码久久久久国产 | 精品1区2区3区 | 黄色av免费网站 | 日日操日日干 | 奇米第四色在线 | 欧美在线一二三区 | av男人资源 | 日韩天堂网| 北条麻妃在线一区 | 欧美一区二区视频免费观看 | 久草免费在线色站 | 美女三级网站 | 欧美精品免费一区二区三区 | 欧美精品在线一区二区 | 国产黄色片子 |