一、前言
? ? ? ? 熟悉開發的兄弟都知道,在寫新增和刪除功能的時候,大多數時候會寫成批量的,原因也很簡單,批量既支持單個也支持多個對象的操作,事情也是發生在這個批量方法的調用上,下面我簡單說一下這個事情。
二、場景描述
? ? ? ? 批量方法的參數可能是一個list集合,里面存放了多個待操作的數據,這是批量方法。當我們操作單個對象的時候,也需要調用批量,那傳參的時候,就涉及到把單個對象封裝成集合,那么封裝的方式有幾種,我下邊羅列一下。
@Testpublic void listTest(){String code = "ITEM-001";//方式1batchOperate(Arrays.asList(code));//方式2batchOperate(Collections.singletonList(code));//方式3batchOperate(CollectionUtil.newArrayList(code));}
? ? ? ? 我羅列了3種方式,但是我見過最多的就是使用第一種方式Arrays.asList(code),如果用了第一種的話,此時IDEA會給個小黃標提示,有點代碼潔癖的人,會按照IDEA推薦的方式進行進一步修改,也就是我們第二種方式Collections.singletonList(code)。
? ? ? ? 對于我個人來說,我推薦用第三種,而且我本人也是使用第三種傳參方式,下面我們運行一下代碼,首先我們來看一下第一種傳參方式。
? ? ? ? 通過運行代碼,居然報add方法報錯,是不是腦瓜子嗡嗡的?我們打個斷點看一下,如下圖所示,我們發現此時進行add方法的list是不是有點奇怪,不是我們常見的java.util下的ArrayList呀,為了更清晰,我們再深入一下,看看Arrays.asList是怎么一回事。
? ? ? ? 進入到Arrays源碼中,我們看到此ArrayList非彼ArrayList,而是Arrays的一個內部類,而且再仔細看看,發現這個內部類中居然沒有add方法,但是確真真實實調用了add方法,它沒有的話,應該是它所繼承的父類中有add方法,我們繼續進入到父類AbstractList中一探究竟。
? ? ? ? 在AbstractList中,我們終于把add方法給揪出來了,從截圖中可以看到,add方法中直接拋出了throw new UnsupportedOperationException(),這也就解釋了為什么在調用add方法的時候報錯了。
? ? ? ? 來我們繼續再看下一個Collections.singletonList(code)是怎么個情況
? ? ? ? 果然,也報錯了,而且報的錯都一樣,那么原因和剛才也大差不差。我們再點進去看看源碼是什么樣的。
? ? ? ? 通過截圖,我們可以看到,SingletonList也是Collections的一個內部類,而且也沒有add方法,并且也繼承自AbstractList,這時候就很明確了,調用add方法就會直接報錯。我們順便再看看其他的操作方法(如下圖所示),基本上也都是報錯,說明繼承自AbstractList的子類是不允許對集合進行操作的。
? ? ? ? 最后再看一下小永哥的選擇測試結果會怎么樣(希望不會翻車......)
? ? ? ? 通過測試截圖可以看到,沒毛病,情況我們就分析到這里了。日常開發過程中應該用哪一種我想現在已經很明確了。
三、焦點訪談
? ? ? ? T哥:小永哥,有沒有人說你很裝呢?
? ? ? ? 小永哥:好像除了你之外,還沒有。
? ? ? ? T哥:你說的這三種傳參有什么意義嗎?隨便一種都行吧,像你說的那種情況基本上不可能發生。
? ? ? ? 小永哥:你說的有你的道理,但是誰能保證自己調用的方法都是自己寫的,絕對安全可靠,我把參數傳過去,人家想這么處理,完全不是我能控制的,但是因為傳參的問題導致了報錯,是不是得排查,為什么能一次性搞定的東西,要繼續浪費時間和精力去處理呢?
? ? ? ? T哥,這次算你有道理.........
四、結語
? ? ? ? 我分享的這些絕不是為了裝,像這種看似簡單,但是平時不常見的錯誤,解決不也得花時間嗎,如果是生產環境報錯,那排查、定位、解決花費的時間更多,有這功夫,我們摸會魚,喝點咖啡它不香嘛。
????????今天就分享到這里,謝謝大家,晚安。
????????