日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當(dāng)前位置:首頁 > 科技  > 軟件

Java程序員易踩的坑及解析

來源: 責(zé)編: 時間:2024-03-18 09:42:57 193觀看
導(dǎo)讀作為Java程序員,在日常開發(fā)中經(jīng)常會遇到一些低級錯誤或者難以理解的情況。以下2個常見的問題,涉及到Java的基礎(chǔ)知識,這2個基礎(chǔ)知識小坑90%以上的程序員都踩過1. ==號比較的坑在比較Integer類型的對象時,一些程序員小伙伴

作為Java程序員,在日常開發(fā)中經(jīng)常會遇到一些低級錯誤或者難以理解的情況。以下2個常見的問題,涉及到Java的基礎(chǔ)知識,這2個基礎(chǔ)知識小坑90%以上的程序員都踩過V7028資訊網(wǎng)——每日最新資訊28at.com

1. ==號比較的坑

在比較Integer類型的對象時,一些程序員小伙伴可能會使用==來判斷它們是否相等。然而,這種用法并不總是正確的。例如,對于Integer對象,==比較的是對象的引用而非值,因此結(jié)果可能出乎意料。我們應(yīng)該養(yǎng)成使用equals()方法來判斷兩個Integer對象是否相等的良好習(xí)慣V7028資訊網(wǎng)——每日最新資訊28at.com

Integer status1 = new Integer(1);Integer status2 = new Integer(1);System.out.println(status1 == status2);

思考:返回結(jié)果是什么?V7028資訊網(wǎng)——每日最新資訊28at.com

答案:falseV7028資訊網(wǎng)——每日最新資訊28at.com

我們小伙伴會說了,Java不是中為了節(jié)省內(nèi)存和提高性能,會對一定范圍內(nèi)的Integer對象進(jìn)行緩存。范圍默認(rèn)是在 -128 到 127 之間,怎么沒有生效?V7028資訊網(wǎng)——每日最新資訊28at.com

我們來看一下Integer構(gòu)造方法V7028資訊網(wǎng)——每日最新資訊28at.com

public Integer(int value) {    this.value = value;}

發(fā)現(xiàn)在Integer構(gòu)造方法中并沒有使用緩存V7028資訊網(wǎng)——每日最新資訊28at.com

思考:Integer緩存在哪里使用?V7028資訊網(wǎng)——每日最新資訊28at.com

在Integer類的valueOf方法中V7028資訊網(wǎng)——每日最新資訊28at.com

public static Integer valueOf(int i) {    if (i >= IntegerCache.low && i <= IntegerCache.high)        return IntegerCache.cache[i + (-IntegerCache.low)];    return new Integer(i);}

如果將代碼修改為如下:V7028資訊網(wǎng)——每日最新資訊28at.com

Integer status1 = 1;  Integer status2 = 1;  System.out.println(status1 == status2);

思考:返回結(jié)果是什么?V7028資訊網(wǎng)——每日最新資訊28at.com

答案:trueV7028資訊網(wǎng)——每日最新資訊28at.com

特別說明: Integer status1 = 1 會默認(rèn)轉(zhuǎn)換為Integer status1 = Integer.valueOf(1)V7028資訊網(wǎng)——每日最新資訊28at.com

編碼要養(yǎng)成良好習(xí)慣,盡量少用==判斷兩個Integer類型數(shù)據(jù)是否相等,而應(yīng)該改成使用equals方法判斷:V7028資訊網(wǎng)——每日最新資訊28at.com

Integer status1 = new Integer(1);Integer status2 = new Integer(1);System.out.println(status1.equals(status2));

輸出結(jié)果trueV7028資訊網(wǎng)——每日最新資訊28at.com

2. BigDecimal的坑

在一些業(yè)務(wù)場景(比如:倉庫數(shù)量,金額)需要設(shè)置成小數(shù),此時字段類型應(yīng)該定義成BigDecimal,而不是Double,避免丟失精度問題V7028資訊網(wǎng)——每日最新資訊28at.com

Double amount1 = 0.02;  Double amount2 = 0.03;  System.out.println(amount2 - amount1);

思考:輸出結(jié)果會是0.1?V7028資訊網(wǎng)——每日最新資訊28at.com

答案:不是輸出結(jié)果如下:V7028資訊網(wǎng)——每日最新資訊28at.com

0.009999999999999998

原因如下:Double類型的兩個參數(shù)相減會轉(zhuǎn)換成二進(jìn)制,Double有效位數(shù)為16位這就會出現(xiàn)存儲小數(shù)位數(shù)不夠的情況,這種情況下就會出現(xiàn)誤差V7028資訊網(wǎng)——每日最新資訊28at.com

將上面代碼進(jìn)行優(yōu)化V7028資訊網(wǎng)——每日最新資訊28at.com

BigDecimal amount1 = new BigDecimal(0.02);BigDecimal amount2 = new BigDecimal(0.03);System.out.println(amount2.subtract(amount1));

思考:結(jié)果會是0.1?不是的,輸出結(jié)果如下:V7028資訊網(wǎng)——每日最新資訊28at.com

0.0099999999999999984734433411404097569175064563751220703125

思考:BigDecimal為啥還是丟失精度?V7028資訊網(wǎng)——每日最新資訊28at.com

查看BigDecimal構(gòu)造方法,注釋說明如下V7028資訊網(wǎng)——每日最新資訊28at.com

/** * 將 a double 轉(zhuǎn)換為 a BigDecimal ,它是 的二進(jìn)制浮點(diǎn)值的精確十進(jìn)制表示 double形式。返回 BigDecimal 的小數(shù)位數(shù)是最小值,因此 (10scale × val) 是整數(shù)。 * 筆記: * 此構(gòu)造函數(shù)的結(jié)果可能有些不可預(yù)測。人們可能會假設(shè)用 Java 編寫 new BigDecimal(0.1) 會創(chuàng)建一個 BigDecimal 完全等于 0.1(未縮放值為 1,小數(shù)位數(shù)為 1),但實(shí)際上它等于 0.1000000000000000000055511151231257827021181583404541015625。這是因?yàn)?0.1 不能完全表示為 a double (或者,就此而言,不能表示為任何有限長度的二進(jìn)制分?jǐn)?shù))。因此,傳遞 給 構(gòu)造函數(shù)的值并不完全等于 0.1,盡管外觀如此。 * String另一方面,構(gòu)造函數(shù)是完全可預(yù)測的:正如人們所期望的那樣,寫入new BigDecimal("0.1")會創(chuàng)建一個BigDecimal完全等于 0.1 的構(gòu)造函數(shù)。因此,通常建議優(yōu)先使用 String 構(gòu)造函數(shù)而不是此構(gòu)造函數(shù)。 * 當(dāng) 必須將 a double 用作 的源BigDecimal時,請注意,此構(gòu)造函數(shù)提供精確的轉(zhuǎn)換;它不會給出與使用Double.toString(double)方法然后使用BigDecimal(String)構(gòu)造函數(shù)將 轉(zhuǎn)換為 double a String 相同的結(jié)果。若要獲得該結(jié)果,請使用該staticvalueOf(double)方法。 * 參數(shù): * val – double 要轉(zhuǎn)換為 BigDecimal的值。 * 拋出: * NumberFormatException – 如果 val 是無限或 NaN。         */public BigDecimal(double val) {    this(val,MathContext.UNLIMITED);}

通過構(gòu)造函數(shù)說明發(fā)現(xiàn),使用BigDecimal構(gòu)造函數(shù)初始化對象,也會丟失精度V7028資訊網(wǎng)——每日最新資訊28at.com

思考:BigDecimal如何才能不丟失精度呢?V7028資訊網(wǎng)——每日最新資訊28at.com

BigDecimal amount3 = new BigDecimal(String.valueOf(0.02));  BigDecimal amount4 = new BigDecimal(String.valueOf(0.03));  System.out.println(amount4.subtract(amount3));

使用BigDecimal.valueOf方法初始化BigDecimal類型參數(shù),也能保證精度不丟失。在新版的阿里巴巴開發(fā)手冊中,也推薦使用這種方式創(chuàng)建BigDecimal參數(shù)。V7028資訊網(wǎng)——每日最新資訊28at.com

BigDecimal amount1 =  BigDecimal.valueOf(0.02);  BigDecimal amount2 =   BigDecimal.valueOf(0.03);  System.out.println(amount2.subtract(amount1));

本文鏈接:http://www.www897cc.com/showinfo-26-76569-0.htmlJava程序員易踩的坑及解析

聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: Redis鎖被別人釋放怎么辦

下一篇: 智能座艙軟件性能與可靠性的評估和改進(jìn)

標(biāo)簽:
  • 熱門焦點(diǎn)
Top 主站蜘蛛池模板: 黔西| 罗甸县| 朔州市| 稷山县| 海阳市| 天峨县| 铜山县| 宣汉县| 诸城市| 当雄县| 青田县| 武威市| 江城| 页游| 西平县| 军事| 盱眙县| 桂平市| 阿瓦提县| 牡丹江市| 青海省| 长治县| 五华县| 屏山县| 淄博市| 文登市| 古田县| 永修县| 江都市| 辽宁省| 屯门区| 凌云县| 盘锦市| 淳化县| 龙南县| 芦山县| 大埔区| 灵寿县| 蓝山县| 会宁县| 黎川县|