自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Java程序員易踩的坑及解析

開發(fā) 前端
我們小伙伴會(huì)說(shuō)了,Java不是中為了節(jié)省內(nèi)存和提高性能,會(huì)對(duì)一定范圍內(nèi)的Integer對(duì)象進(jìn)行緩存。范圍默認(rèn)是在 -128 到 127 之間,怎么沒(méi)有生效?

作為Java程序員,在日常開發(fā)中經(jīng)常會(huì)遇到一些低級(jí)錯(cuò)誤或者難以理解的情況。以下2個(gè)常見的問(wèn)題,涉及到Java的基礎(chǔ)知識(shí),這2個(gè)基礎(chǔ)知識(shí)小坑90%以上的程序員都踩過(guò)

1. ==號(hào)比較的坑

在比較Integer類型的對(duì)象時(shí),一些程序員小伙伴可能會(huì)使用==來(lái)判斷它們是否相等。然而,這種用法并不總是正確的。例如,對(duì)于Integer對(duì)象,==比較的是對(duì)象的引用而非值,因此結(jié)果可能出乎意料。我們應(yīng)該養(yǎng)成使用equals()方法來(lái)判斷兩個(gè)Integer對(duì)象是否相等的良好習(xí)慣

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

思考:返回結(jié)果是什么?

答案:false

我們小伙伴會(huì)說(shuō)了,Java不是中為了節(jié)省內(nèi)存和提高性能,會(huì)對(duì)一定范圍內(nèi)的Integer對(duì)象進(jìn)行緩存。范圍默認(rèn)是在 -128 到 127 之間,怎么沒(méi)有生效?

我們來(lái)看一下Integer構(gòu)造方法

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

發(fā)現(xiàn)在Integer構(gòu)造方法中并沒(méi)有使用緩存

思考:Integer緩存在哪里使用?

在Integer類的valueOf方法中

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

如果將代碼修改為如下:

Integer status1 = 1;
  Integer status2 = 1;

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

思考:返回結(jié)果是什么?

答案:true

特別說(shuō)明: Integer status1 = 1 會(huì)默認(rèn)轉(zhuǎn)換為Integer status1 = Integer.valueOf(1)

編碼要養(yǎng)成良好習(xí)慣,盡量少用==判斷兩個(gè)Integer類型數(shù)據(jù)是否相等,而應(yīng)該改成使用equals方法判斷:

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

輸出結(jié)果true

2. BigDecimal的坑

在一些業(yè)務(wù)場(chǎng)景(比如:倉(cāng)庫(kù)數(shù)量,金額)需要設(shè)置成小數(shù),此時(shí)字段類型應(yīng)該定義成BigDecimal,而不是Double,避免丟失精度問(wèn)題

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

思考:輸出結(jié)果會(huì)是0.1?

答案:不是輸出結(jié)果如下:

0.009999999999999998

原因如下:Double類型的兩個(gè)參數(shù)相減會(huì)轉(zhuǎn)換成二進(jìn)制,Double有效位數(shù)為16位這就會(huì)出現(xiàn)存儲(chǔ)小數(shù)位數(shù)不夠的情況,這種情況下就會(huì)出現(xiàn)誤差

將上面代碼進(jìn)行優(yōu)化

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

思考:結(jié)果會(huì)是0.1?不是的,輸出結(jié)果如下:

0.0099999999999999984734433411404097569175064563751220703125

思考:BigDecimal為啥還是丟失精度?

查看BigDecimal構(gòu)造方法,注釋說(shuō)明如下

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

通過(guò)構(gòu)造函數(shù)說(shuō)明發(fā)現(xiàn),使用BigDecimal構(gòu)造函數(shù)初始化對(duì)象,也會(huì)丟失精度

思考:BigDecimal如何才能不丟失精度呢?

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ā)手冊(cè)中,也推薦使用這種方式創(chuàng)建BigDecimal參數(shù)。

BigDecimal amount1 =  BigDecimal.valueOf(0.02);
  BigDecimal amount2 =   BigDecimal.valueOf(0.03);
  System.out.println(amount2.subtract(amount1));
責(zé)任編輯:武曉燕 來(lái)源: springboot葵花寶典
相關(guān)推薦

2022-07-15 08:20:54

Java基礎(chǔ)知識(shí)

2025-04-29 08:30:00

迭代器失效C++編程

2025-04-03 12:30:00

C 語(yǔ)言隱式類型轉(zhuǎn)換代碼

2018-02-06 08:36:02

簡(jiǎn)歷程序員面試

2020-05-06 11:33:49

程序員技能求職

2015-09-16 09:57:41

swoolePHP程序員

2024-12-17 17:24:24

2017-11-28 14:15:38

開發(fā)者故事

2014-08-13 11:11:58

程序員

2018-05-31 15:22:53

程序員女程序男性程序員

2015-08-18 15:22:59

程序員成長(zhǎng)階段

2020-08-11 07:31:39

JavaVolatile模型

2020-01-12 19:10:30

Java程序員數(shù)據(jù)

2012-11-08 09:49:30

C++Java程序員

2013-08-20 09:33:59

程序員

2022-09-25 21:58:27

程序員

2014-07-29 10:30:16

JavaJava程序員

2021-07-28 14:37:57

WKWebviewh5網(wǎng)絡(luò)

2012-11-02 13:47:31

Java程序員編程

2021-10-18 21:41:10

Go程序員 Defer
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)