<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>

          一不小心就踩了lombok的坑?

          共 4266字,需瀏覽 9分鐘

           ·

          2021-07-28 16:02

          點擊上方“Java金融”,選擇“設為星標”

          后臺回復"888"獲取bat面試題集

          引言

          今天中午正在帶著耳機遨游在代碼的世界里,被運營在群里@了,氣沖沖的反問我最近有刪生產(chǎn)的用戶數(shù)據(jù)的嗎?我肯定客氣的回答道沒有呀?生產(chǎn)的數(shù)據(jù)我怎么能隨隨便便可以刪除,這可是公司的紅線,再說了我也沒有數(shù)據(jù)庫的刪除權(quán)限啊,不過查詢權(quán)限還是有的。趕緊登上堡壘機,然后去生產(chǎn)數(shù)據(jù)庫查一下數(shù)據(jù),查了一下數(shù)據(jù)是還在的,嚇死了,數(shù)據(jù)還在問題就不大了,無非就是應用程序出問題了,趕緊打開代碼查看下,為什么會少了一條用戶數(shù)據(jù),看了下代碼貌似沒啥問題就是比較簡單的一個邏輯,直接從DB通過分頁查詢數(shù)據(jù)給到前端,然后前端負責展示,沒有啥復雜的邏輯。心想肯定是前端的問題,肯定是他少展示了數(shù)據(jù),立馬把問題也甩給了他,讓他幫忙配合一起看看是否是前端的問題,然后自己也仔細看看代碼,不到一分鐘前端說他展示的數(shù)據(jù)沒有問題,都是后端給到的,沒有漏掉展示的。那就是后端的bug了羅。肉眼望去覺得可能出問題的就是分頁導致的數(shù)據(jù)丟了。不過這個分頁插件是全公司都在用,應該不至于出問題吧,找不到問題只能讓測試幫忙在測試環(huán)境試試,看看是否可以復現(xiàn)。

          測試環(huán)境復現(xiàn)

          仔細看了一眼,居然有個去重的方法,去重邏輯也比較簡單就是把list通過轉(zhuǎn)為set去下重,看下來應該就是這個去重方法有問題了 大致寫了單元測試模仿了下生產(chǎn)的數(shù)據(jù),大致邏輯如下:

          public static void main(String[] args) {
                  Set<UserDTO> userSet = new HashSet<>();
                  UserDTO userDTO = new UserDTO();
                  userDTO.setId(1);
                  userDTO.setUserName("java金融");

                  UserDTO userDTO1 = new UserDTO();
                  userDTO1.setId(2);
                  userDTO1.setUserName("java金融");
                  userSet.add(userDTO);
                  userSet.add(userDTO1);
                  System.out.println(userSet.size());
                  System.out.println(userDTO1.equals(userDTO));
              }

              @Data
              static class UserDTO extends BaseDTO {
                  private String userName;
              }
              @Data
              static class BaseDTO {
                  private Integer id;
              }

          我們可以輸出結(jié)果set集合的長度是1,user1user2 是相等的,明明兩個userID是不一樣的,為何會相等,我們知道set可以去重 是因為Set的操作,都是通過操作map來實現(xiàn)的,setadd其實就是調(diào)用mapput方法,mapput方法我相信大家應該都去看過其源碼,這里就不詳細再說了,大概流程就是通過key通過hash算法定位到數(shù)組的下標,先判斷keyhash是否相等,如果相等再去判斷key的value相等,如果都相等就會覆蓋原來的值。我們上面這個例子就是對象的hashvalue都相等導致,但是我們的兩個對象user1user2 應該是不等的,因為ID不等,那為什么會相等列?我們仔細看下上面的代碼,我們使用了lombok里面@Data注解,我們可以看看這個注解幫我們生成了哪些方法通過上面的對比我們可以看出@Data注解幫我們生成了 注在類上,提供類的get、set、equals、hashCode、canEqual、toString方法,這個注解確實比較方便。上面那個bug 就是因為它生成的equals方法有問題,我們可以把上述代碼編譯下,然后把class 里面生成的equals方法拷貝出來看看

          通過上述生成的代碼我們可以看出equals方法只比較了userName這個字段,也就是當前類的字段,并沒有去比較父類的字段,這就是導致兩個對象相等的原因,我們既然找到問題了,那解決問題就比較簡單。

          解決問題

          • 手動重寫equalshashCode方法,這種方法肯定是不推薦的,我們既然用了lombok就是為了解放我們的雙手,是代碼變得更加簡潔。
          • 在比較的類上加上@EqualsAndHashCode(callSuper = true) callSuper = true 會包含父類的equalshashCode方法 我們可以對比下加上@EqualsAndHashCode(callSuper = true)和沒有加上這個注解生成的equals方法的代碼差異。差異點還是很明顯的,加入了@EqualsAndHashCode(callSuper = true) 會去調(diào)用父類的equals方法比較,所以這個注解也能夠解決這個問題。
          • 這樣加上注解確實可以解決問題,但是每個類上面都要加上這個注解,這也是個體力活。我們可以再找找其他的方案,例如有沒有比如配置文件設置下什么的,然后就能全局生效了。最終通過查詢資料發(fā)現(xiàn)我們我們寫一個lombok.config的配置文件放在我們項目的根目錄下面,內(nèi)容寫上lombok.equalsAndHashCode.callSuper = call效果等同于@EqualsAndHashCode(callSuper = true),這樣的話我們就不需要為每個類都去加上這個注釋了,相當于在這個項目下面只要用到了@Data注解的類都會為其加上@EqualsAndHashCode(callSuper = true)通過配置文件的方式就可以全局生效。

          總結(jié)

          • 我們再來回顧下上面的問題,歸根結(jié)底還是由于對象的equals方法使用不當引起的,所以我們在如果在判斷自定義對象業(yè)務判斷相等的時候需要去重寫下hashCodeequals方法,重寫的時候我們可以通過idea來生成,生成后最好還是去看一眼,看看生成的是否符合我們的業(yè)務要求。

          • 我們在工作中操作一些常見的容器類比如Set、Map等來實現(xiàn)一些我們自己的業(yè)務,我們還是有必要去看看它們的源碼的,就比如我們通過Set來進行去重,如果我們是使用的自定義對象的話,如果沒有重寫hashCodeequals方法的話,去重就會去不成功,我們只有了解了它,才能真正的去用好它。在關于hashCodeequals 阿里巴巴開發(fā)手冊也有明確的說到

          • lombok 用起來還是挺爽的,但是還是有一些細節(jié)需要稍微注意下。使用前可以大概的去看看它的官網(wǎng)提供的內(nèi)容,不然出現(xiàn)莫名其妙的問題你都不知道如何下手。這個就有點類似于我們使用SpringBoot一樣,用起來非常爽,但是如果遇到莫名其妙的bug解決起來就比較頭疼。

          • 最后我們再來回顧幾道關于hashCodeequals的比較常見的面試題?其實如果我們只要真正看過HashMap的源碼的話,這下面幾個面試題還是非常簡單的。什么情況下需要我們?nèi)ブ貙?方法?如果只重寫equals方法不重寫HashCode可以嗎?equals ,== 和hashcode()的區(qū)別?

          最后為了感謝大家的支持,明天18點朋友圈決定送兩本技術書籍,書籍可以自己在京東選價格為30元至80元區(qū)間的(不想要書的也可以折現(xiàn)50元)。獲取書籍的方式很簡單,只要朋友圈點個贊就可以了,具體第幾個贊可以拿到書那就朋友圈見了。下面是二維碼歡迎大家掃碼加下好友哦。也可以微信搜javajr8也可以添加好友哦。

          結(jié)束

          • 由于自己才疏學淺,難免會有紕漏,假如你發(fā)現(xiàn)了錯誤的地方,還望留言給我指出來,我會對其加以修正。
          • 如果你覺得文章還不錯,你的轉(zhuǎn)發(fā)、分享、贊賞、點贊、留言就是對我最大的鼓勵。
          • 感謝您的閱讀,十分歡迎并感謝您的關注。

          文章有幫助的話,在看,轉(zhuǎn)發(fā)吧。

          謝謝支持喲 (*^__^*)

          瀏覽 56
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <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>
                  女人天堂中文字幕 | 一级aa免费视频 | 成人高清无码视频在线免费观看 | 无码一区免费 | 围产精品久久久久久久妞妞 |