<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          為什么高級(jí)程序員都不用 “ ! = null ' 做判空

          共 570字,需瀏覽 2分鐘

           ·

          2021-11-03 22:30

          點(diǎn)擊“藍(lán)字”,關(guān)注,置頂公眾號(hào)

          每日技術(shù)干貨,第一時(shí)間送達(dá)!

          問(wèn)題


          為了避免空指針調(diào)用,我們經(jīng)常會(huì)看到這樣的語(yǔ)句


          ...if (someobject != null) {    someobject.doCalc();}...


          最終,項(xiàng)目中會(huì)存在大量判空代碼,多么丑陋繁冗!如何避免這種情況?我們是否濫用了判空呢?


          精華回答


          這是初、中級(jí)程序猿經(jīng)常會(huì)遇到的問(wèn)題。他們總喜歡在方法中返回null,因此,在調(diào)用這些方法時(shí),也不得不去判空。另外,也許受此習(xí)慣影響,他們總潛意識(shí)地認(rèn)為,所有的返回都是不可信任的,為了保護(hù)自己程序,就加了大量的判空。


          吐槽完畢,回到這個(gè)題目本身:


          進(jìn)行判空前,請(qǐng)區(qū)分以下兩種情況:


          1、null 是一個(gè)有效有意義的返回值(Where null is a valid response in terms of the contract; and)

          2、null是無(wú)效有誤的(Where it isn't a valid response.)


          你可能還不明白這兩句話的意思,不急,繼續(xù)往下看,接下來(lái)將詳細(xì)討論這兩種情況


          先說(shuō)第2種情況


          null就是一個(gè)不合理的參數(shù),就應(yīng)該明確地中斷程序,往外拋錯(cuò)誤。這種情況常見(jiàn)于api方法。例如你開(kāi)發(fā)了一個(gè)接口,id是一個(gè)必選的參數(shù),如果調(diào)用方?jīng)]傳這個(gè)參數(shù)給你,當(dāng)然不行。你要感知到這個(gè)情況,告訴調(diào)用方“嘿,哥們,你傳個(gè)null給我做甚"。


          相對(duì)于判空語(yǔ)句,更好的檢查方式有兩個(gè)


          (1)assert語(yǔ)句,你可以把錯(cuò)誤原因放到assert的參數(shù)中,這樣不僅能保護(hù)你的程序不往下走,而且還能把錯(cuò)誤原因返回給調(diào)用方,豈不是一舉兩得。(原文介紹了assert的使用,這里省略)


          (2)也可以直接拋出空指針異常。上面說(shuō)了,此時(shí)null是個(gè)不合理的參數(shù),有問(wèn)題就是有問(wèn)題,就應(yīng)該大大方方往外拋。


          第1種情況會(huì)更復(fù)雜一些。


          這種情況下,null是個(gè)”看上去“合理的值,例如,我查詢數(shù)據(jù)庫(kù),某個(gè)查詢條件下,就是沒(méi)有對(duì)應(yīng)值,此時(shí)null算是表達(dá)了“空”的概念。


          這里給一些實(shí)踐建議:


          1、假如方法的返回類型是collections,當(dāng)返回結(jié)果是空時(shí),你可以返回一個(gè)空的collections(empty list),而不要返回null,這樣調(diào)用側(cè)就能大膽地處理這個(gè)返回,例如調(diào)用側(cè)拿到返回后,可以直接print list.size(),又無(wú)需擔(dān)心空指針問(wèn)題。(什么?想調(diào)用這個(gè)方法時(shí),不記得之前實(shí)現(xiàn)該方法有沒(méi)按照這個(gè)原則?所以說(shuō),代碼習(xí)慣很重要!如果你養(yǎng)成習(xí)慣,都是這樣寫代碼(返回空collections而不返回null),你調(diào)用自己寫的方法時(shí),就能大膽地忽略判空)


          2、返回類型不是collections,又怎么辦呢?


          那就返回一個(gè)空對(duì)象(而非null對(duì)象),下面舉個(gè)“栗子”,假設(shè)有如下代碼


          public interface Action {  void doSomething();}
          public interface Parser { Action findAction(String userInput);}


          其中,Parse有一個(gè)接口FindAction,這個(gè)接口會(huì)依據(jù)用戶的輸入,找到并執(zhí)行對(duì)應(yīng)的動(dòng)作。假如用戶輸入不對(duì),可能就找不到對(duì)應(yīng)的動(dòng)作(Action),因此findAction就會(huì)返回null,接下來(lái)action調(diào)用doSomething方法時(shí),就會(huì)出現(xiàn)空指針。


          解決這個(gè)問(wèn)題的一個(gè)方式,就是使用Null Object pattern(空對(duì)象模式)


          我們來(lái)改造一下


          類定義如下,這樣定義findAction方法后,確保無(wú)論用戶輸入什么,都不會(huì)返回null對(duì)象

          public class MyParser implements Parser {  private static Action DO_NOTHING = new Action() {    public void doSomething() { /* do nothing */ }  };
          public Action findAction(String userInput) { // ... if ( /* we can't find any actions */ ) { return DO_NOTHING; } }}


          對(duì)比下面兩份調(diào)用實(shí)例


          1、冗余:每獲取一個(gè)對(duì)象,就判一次空


          Parser parser = ParserFactory.getParser();if (parser == null) {  // now what?  // this would be an example of where null isn't (or shouldn't be) a valid response}Action action = parser.findAction(someInput);if (action == null) {  // do nothing} else {  action.doSomething();}


          2、精簡(jiǎn)


          ParserFactory.getParser().findAction(someInput).doSomething();


          因?yàn)闊o(wú)論什么情況,都不會(huì)返回空對(duì)象,因此通過(guò)findAction拿到action后,可以放心地調(diào)用action的方法。


          其他回答精選


          1、如果要用equal方法,請(qǐng)用object<不可能為空>.equal(object<可能為空>))


          例如:


          使用

          "bar".equals(foo)


          而不是

          foo.equals("bar")


          2、Java8或者guava lib中,提供了Optional類,這是一個(gè)元素容器,通過(guò)它來(lái)封裝對(duì)象,可以減少判空。不過(guò)代碼量還是不少。不爽。


          3、如果你想返回null,請(qǐng)挺下來(lái)想一想,這個(gè)地方是否更應(yīng)該拋出一個(gè)異常


          stackoverflow鏈接:

          http://stackoverflow.com/questions/271526/avoiding-null-statements-in-java?page=2&tab=votes#tab-top


          來(lái)源:blog.csdn.net/lizeyang/article/details/40040817




          往期推薦



          聊聊 Java 泛型通配符 T,E,K,V,?

          Redis 單例、主從、sentinel 以及集群的配置方式及優(yōu)缺點(diǎn)對(duì)比

          使用Java 這幾個(gè)常用工具類庫(kù),助你告別996,建議收藏!

          數(shù)據(jù)庫(kù)分表分庫(kù)策略

          你對(duì)索引的理解有多少?

          關(guān)于select......for update語(yǔ)句會(huì)加什么鎖?



          瀏覽 68
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  抽插综合网| 操穴网站| 日韩色情在线观看 | 色日本导航 | 国模精品 |