Java中Boolean引發(fā)缺陷的解決
最近在項(xiàng)目測試中,發(fā)現(xiàn)一個(gè)由Boolean引發(fā)的缺陷,主要是覺得這個(gè)問題比較有意思,而且code review過程也不太容易發(fā)現(xiàn),缺陷本質(zhì)上歸類于契約問題。
問題描述
應(yīng)用A與應(yīng)用B之間存在調(diào)用關(guān)系,即B提供接口給A調(diào)用。A-B之間的契約存在一個(gè)參數(shù)類型是布爾類型。此參數(shù)業(yè)務(wù)場景是只有在特定情況下會傳值true,其他業(yè)務(wù)場景A會傳默認(rèn)值false。
由于此前溝通存在分歧,B側(cè)開發(fā)同學(xué)在定義契約時(shí)候此參數(shù)使用了Boolean,而非boolean類型。詭異的是開發(fā)在聯(lián)調(diào)過程由于正常傳值沒發(fā)現(xiàn)問題,在提測后測試測試異常場景才發(fā)現(xiàn)這個(gè)問題。
介紹具體缺陷之前,我們先了解下Boolean與boolean的區(qū)別。
Boolean與boolean的區(qū)別
Java 在java.lang包中提供了Boolean類。Boolean將原始類型 boolean 的值包裝在一個(gè)對象中。布爾類型的對象包含一個(gè)類型為布爾值的字段。此外,此類還提供了一些有用的方法,例如在處理布爾變量時(shí)將布爾值轉(zhuǎn)換為字符串以及將字符串轉(zhuǎn)換為布爾值。
Boolean 類提供了兩個(gè)用于創(chuàng)建 Boolean 對象的構(gòu)造函數(shù)。
Boolean b = newBoolean(boolean value); Boolean b = newBoolean(String s);
一個(gè)簡單的代碼示例:
// Java program to demonstrate parseBoolean() method public class Test { public static void main(String[] args) { // parsing different Strings boolean b1 = Boolean.parseBoolean("True"); boolean b2 = Boolean.parseBoolean("TruE"); boolean b3 = Boolean.parseBoolean("False"); boolean b4 = Boolean.parseBoolean("FALSE"); boolean b5 = Boolean.parseBoolean("qualityassurance"); System.out.println(b1); System.out.println(b2); System.out.println(b3); System.out.println(b4); System.out.println(b5); } } ? true true false false false
在Java編程語言中,Boolean與boolean都是布爾類型的數(shù)據(jù)。但是它們之間有一些區(qū)別:
1. Boolean是一個(gè)類,而boolean是一個(gè)原始數(shù)據(jù)類型。Boolean類型的變量在初始化之前可以為null,而boolean類型的變量不能。
2. Boolean類型提供了一些方法,例如valueOf()和parseBoolean()等,以便對其進(jìn)行操作。但是,boolean類型沒有這些方法,因?yàn)樗窃碱愋汀?/p>
3. Boolean類型通常用于需要在對象中存儲布爾值的情況下,而boolean類型通常用于本地變量和數(shù)組等原始數(shù)據(jù)類型的情況。
4. 在自動裝箱和拆箱方面,兩者也有所不同。Boolean類型可以自動裝箱和拆箱,而boolean類型只能在Java 5或更高版本中進(jìn)行自動裝箱和拆箱。
缺陷還原
舉例比較簡單,當(dāng)然實(shí)際業(yè)務(wù)邏輯要復(fù)雜很多。
定義一個(gè)Payment類,其中包含Boolean類型的屬性,用于區(qū)分此筆支付是否支持打折扣。
import lombok.Data; /** * @author qualityassurance * @version Payment.java, v 0.1 2023年03月19日 15:52 */ @Data public class Payment { /** * 支付金額 */ private int amount; /** * 是否可以用折扣 */ private Boolean isDiscount; }
實(shí)現(xiàn)一個(gè)函數(shù)(API),功能是如果此筆交易支持打折扣,則交易價(jià)格減半,否則計(jì)算原價(jià)。
public class DiscountFunction { ? public int calculateAmount(Payment payment){ /** * 若isDiscount=true,則價(jià)格砍半 */ if (payment.getIsDiscount().booleanValue()){ return payment.getAmount()/2; } return payment.getAmount(); } }
測試類,實(shí)現(xiàn)兩個(gè)case,分別是打折扣的場景和不打折扣的場景。
public class DiscountFunctionTest { ? /** * 若isDiscount=true,則價(jià)格砍半 */ @Test public void isDiscountTest(){ Payment payment = new Payment(); payment.setAmount(1000); payment.setIsDiscount(true); DiscountFunction discountFunction = new DiscountFunction(); int amount = discountFunction.calculateAmount(payment); Assert.assertEquals(payment.getAmount()/2, amount); } ? /** * 若isDiscount=false,則價(jià)格不變 */ @Test public void isNotDiscountTest(){ Payment payment = new Payment(); payment.setAmount(1000); DiscountFunction discountFunction = new DiscountFunction(); int amount = discountFunction.calculateAmount(payment); Assert.assertEquals(payment.getAmount(), amount); } }
運(yùn)行結(jié)果:
可以看到isNotDiscountTest用例執(zhí)行過程報(bào)了NPE,分析代碼得知在下圖那里報(bào)的,完美復(fù)現(xiàn)我在測試過程中的發(fā)現(xiàn)的缺陷。
修復(fù)方案:
1. 將Payment類的屬性isDiscount類型改為小布爾boolean。
2. 在使用大布爾類型時(shí),代碼的判斷邏輯要增加判Null。
缺陷分析:
分享這個(gè)缺陷主要是為了提醒大家在看到大布爾Boolean的時(shí)候,一定要重點(diǎn)關(guān)注if判定條件開發(fā)是否考慮的全面,最好是形成這樣的條件反射。
到此這篇關(guān)于Java中Boolean引發(fā)缺陷的解決的文章就介紹到這了,更多相關(guān)Java Boolean缺陷內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot+Thymeleaf+ECharts實(shí)現(xiàn)大數(shù)據(jù)可視化(基礎(chǔ)篇)
本文主要介紹了SpringBoot+Thymeleaf+ECharts實(shí)現(xiàn)大數(shù)據(jù)可視化,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧<BR>2022-06-06Java查找不重復(fù)無序數(shù)組中是否存在兩個(gè)數(shù)字的和為某個(gè)值
今天小編就為大家分享一篇關(guān)于Java查找不重復(fù)無序數(shù)組中是否存在兩個(gè)數(shù)字的和為某個(gè)值,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2019-01-01淺析SpringMVC中的適配器HandlerAdapter
這篇文章主要介紹了SpringMVC中的適配器HandlerAdapter的相關(guān)資料,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-01-01解決swagger2中@ApiResponse的response不起作用
這篇文章主要介紹了解決swagger2中@ApiResponse的response不起作用問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-06-06使用Java實(shí)現(xiàn)通用樹形結(jié)構(gòu)構(gòu)建工具類
這篇文章主要為大家詳細(xì)介紹了如何使用Java實(shí)現(xiàn)通用樹形結(jié)構(gòu)構(gòu)建工具類,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2025-03-03Java中HashMap和TreeMap的區(qū)別深入理解
首先介紹一下什么是Map。在數(shù)組中我們是通過數(shù)組下標(biāo)來對其內(nèi)容索引的,而在Map中我們通過對象來對對象進(jìn)行索引,用來索引的對象叫做key,其對應(yīng)的對象叫做value2012-12-12