最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

一場由Java中Integer引發(fā)的踩坑實戰(zhàn)

 更新時間:2022年11月10日 11:14:00   作者:我是老姚  
Java中的數(shù)據(jù)類型分為基本數(shù)據(jù)類型和復(fù)雜數(shù)據(jù)類型int是前者而integer是后者(也就是一個類),下面這篇文章主要給大家介紹了關(guān)于由Java中Integer引發(fā)的踩坑實戰(zhàn),需要的朋友可以參考下

看過阿里巴巴開發(fā)手冊的同學(xué)應(yīng)該都會對Integer臨界值127有點印象。

原文中寫的是:

【強制】所有整型包裝類對象之間值的比較,全部使用 equals 方法比較。

說明:對于 Integer var = ? 在-128 至 127 之間的賦值,Integer 對象是在 IntegerCache.cache 產(chǎn)生,

會復(fù)用已有對象,這個區(qū)間內(nèi)的 Integer 值可以直接使用==進行判斷,但是這個區(qū)間之外的所有數(shù)據(jù),都

會在堆上產(chǎn)生,并不會復(fù)用已有對象,這是一個大坑,推薦使用 equals 方法進行判斷。

沒錯,文中要求Integer對象比較的時候必須要用equals進行。

然后很多同學(xué)對于為什么要這么干沒什么感覺。對于IntegerCache.cache也沒什么感覺。

很多時候我們寫的代碼可能是這樣的:

Integer num = 127;
if(num==128){
	//...
}

這種情況下,我們拿Integer和一個數(shù)字比較的時候,是不會出什么問題。

然后如果我們這樣寫

Integer num1 = 127;
num1++;
Integer num2=  128;
if (num1 == num2) {
    System.out.println(true);
}
else{
    System.out.println(false);
}

神奇的事情發(fā)生了,num1和num2雖然都是128,但是他們并不相等。

這是因為Integer的值如果是-128~127之間的時候,Integer并不會創(chuàng)建新的對象,而是從IntegerCache.cache中取出的,所以他們隨便比較都沒有問題。

但是如果超出了這個范圍,就不一樣了。

不信你可以試試下面的代碼:

Integer num1 = 127;
Integer num2=  127;
if (num1 == num2) {
    System.out.println(true);
}
else{
    System.out.println(false);
}

=================================

可惜的是工作中常常忘記了這一點,于是一場意外發(fā)生了。

本人前段時間寫的一段代碼中有下面一段:

String standardItemNameStr = sampleStandardItemList.stream()
  .filter(item -> item.getSampleId()==sample.getSampleId())
  .map(item -> item.getStandardItemName()).collect(Collectors.joining("、"));

系統(tǒng)剛剛上線的時候一切NICE,運行很正常。突然有一天出事了??蛻舾答伋鯞UG了。

本該顯示數(shù)據(jù)的地方,成了空值。

自己在本地測試,一切OK。代碼檢測了十遍以上,沒發(fā)現(xiàn)什么問題。

把生產(chǎn)環(huán)境的數(shù)據(jù)DOWN下來一跑發(fā)現(xiàn)其中第二行item.getSampleId()的值是180,這時突然想起Integer的這個設(shè)定。二話不說,修改為下面的代碼,一切恢復(fù)正常。

String standardItemNameStr = sampleStandardItemList.stream()
    .filter(item -> item.getSampleId() .equals(sample.getSampleId()))
    .map(item -> item.getStandardItemName()).collect(Collectors.joining("、"));

這個問題雖然很簡單,但還是很容易忽略的。由此也擴展思考了一下,去測試一下Double、Float包裝類,并沒有catch這類的設(shè)計思路。

原因嘛應(yīng)該也很簡單,Integer是整數(shù),很多時候我們用Integer的時候需要用到的值確實是比較小的,所以官方做個catch確實能起到提高執(zhí)行效率的作用,而且這個緩存命中率還是比較高的,但是小數(shù)的主要用途是在小數(shù)方面,如果要做catch的話,那數(shù)量可就太多了。

那么byte、short、long的包裝類會不會也有catch的設(shè)計呢?

補充:Java Integer比較中的那些坑

前幾天同事偶然遇到的一個問題,在list中查詢出重復(fù)的值,留下第一個,其余刪除。

ArrayList<Integer> a//a中裝有要操作的數(shù)據(jù),都是數(shù)字
for(int i;i<a.size();i++){
    //....遍歷
    for(int j=i;j<a.size();j++){
        if(a.get(i)==a.get(j)){
        a.remove(j);
        }
    }
}

然后喜聞樂見的程序出問題了:程序無法將相同的值除第一個外刪除掉。說起來這也是一個比較基礎(chǔ)性的問題。

int為基本類型,Integer類型為基本包裝類型。因而可以將Integer當(dāng)做一個對象來理解,所以在上面的代碼示例中,用==來比較2個對象的引用無疑就是在搞笑了,地址都不一樣,怎么可能返回true。

但是這里存在著一些坑,就是Integer有時候用==比較是可以得到true的(值相同),原因如下:

在-128至127之間的賦值,Integer對象是在IntegerCache.cache產(chǎn)生,會復(fù)用已有對象,這個區(qū)間內(nèi)的Integer值可以直接使用==進行判斷,但是這個區(qū)間之外的所有數(shù)據(jù),都會在堆上產(chǎn)生,并不會復(fù)用已有對象。

所以推薦都使用equals比較。

附上int類型自動裝箱為Integer時的源代碼(IntegerCache.low為-128)

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

這里還牽涉到了一點,就是這里為什么不直接用int類型呢?這是因為ArrayList中只接受Object對象,實際情況如下:

ArrayList al=new ArrayList();
int n=40;
Integer nI=new Integer(n);
al.add(n);//不可以
al.add(nI);//可以

總結(jié)

到此這篇關(guān)于一場由Java中Integer引發(fā)的踩坑實戰(zhàn)的文章就介紹到這了,更多相關(guān)Java中Integer踩坑內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • springboot集成普羅米修斯(Prometheus)的方法

    springboot集成普羅米修斯(Prometheus)的方法

    這篇文章主要介紹了springboot集成普羅米修斯(Prometheus)的方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • 深入學(xué)習(xí)Java 動態(tài)代理

    深入學(xué)習(xí)Java 動態(tài)代理

    Java 動態(tài)代理機制的出現(xiàn),使得 Java 開發(fā)人員不用手工編寫代理類,只要簡單地指定一組接口及委托類對象,便能動態(tài)地獲得代理類。下面小編和大家來一起學(xué)習(xí)一下吧
    2019-05-05
  • springboot @Valid注解對嵌套類型的校驗功能

    springboot @Valid注解對嵌套類型的校驗功能

    這篇文章主要介紹了springboot~@Valid注解對嵌套類型的校驗,主要介紹 @Valid在項目中的使用,需要的朋友可以參考下
    2018-05-05
  • 解決mybatis plus報錯Invalid bound statement (not found):問題

    解決mybatis plus報錯Invalid bound statement 

    在使用MyBatis時遇到InvalidBoundStatement異常,常因多個MapperScan配置沖突或者包掃描路徑設(shè)置錯誤,解決方法包括保留一個MapperScan聲明、檢查jar包沖突、確保命名空間和掃描路徑正確,使用@TableId注解指定主鍵
    2024-11-11
  • 利用Java自寫一個生成ID的工具類

    利用Java自寫一個生成ID的工具類

    平時項目中只要涉及表,那么一定能接觸到眾多各式各樣的ID編號。本文將通過Java語言實現(xiàn)手寫一個ID生成工具類,需要的小伙伴可以參考一下
    2022-11-11
  • Java pdu短信解碼全面解析

    Java pdu短信解碼全面解析

    本文是根據(jù)python的方法改寫的pdu短信解碼,非常不錯,代碼簡單易懂具有參考借鑒價值,感興趣的朋友一起看看吧
    2016-10-10
  • SpringBoot定時任務(wù)兩種(Spring Schedule 與 Quartz 整合 )實現(xiàn)方法

    SpringBoot定時任務(wù)兩種(Spring Schedule 與 Quartz 整合 )實現(xiàn)方法

    本篇文章主要介紹了SpringBoot定時任務(wù)兩種(Spring Schedule 與 Quartz 整合 )實現(xiàn)方法,詳細的介紹了Spring Schedule 與 Quartz 整合的兩種方法,有興趣的可以了解一下。
    2017-03-03
  • 后端返回各種圖片形式在前端的轉(zhuǎn)換及展示方法對比

    后端返回各種圖片形式在前端的轉(zhuǎn)換及展示方法對比

    這篇文章主要給大家介紹了關(guān)于后端返回各種圖片形式在前端的轉(zhuǎn)換及展示方法對比的相關(guān)資料,文中通過圖文介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2023-06-06
  • SpringBoot注冊第三方Bean的方法總結(jié)

    SpringBoot注冊第三方Bean的方法總結(jié)

    眾所周知,SpringBoot默認會掃描啟動類所在的包及其子包,一般我們都是在需要的類上通過注解的方式去將Bean注冊交給IOC進行管理,但是注冊第三方Bean的方案卻不支持,所以本文給大家介紹了SpringBoot注冊第三方Bean的方法,需要的朋友可以參考下
    2024-01-01
  • MyBatis實現(xiàn)動態(tài)SQL的方法

    MyBatis實現(xiàn)動態(tài)SQL的方法

    動態(tài)SQL是MyBatis強大特性之一,極大的簡化我們拼裝SQL的操作,本文主要介紹了MyBatis實現(xiàn)動態(tài)SQL的方法,具有一定的參考價值,感興趣的可以了解一下
    2024-06-06

最新評論

博白县| 临夏县| 宜君县| 延长县| 上饶县| 六枝特区| 北票市| 东山县| 永嘉县| 鄂州市| 汝城县| 花垣县| 古田县| 安吉县| 岑巩县| 雷波县| 富民县| 温州市| 玉屏| 葵青区| 博客| 纳雍县| 宜丰县| 曲阳县| 贺兰县| 永德县| 保靖县| 长白| 东乡族自治县| 缙云县| 元江| 永丰县| 申扎县| 中方县| 河西区| 都江堰市| 蛟河市| 定边县| 德格县| 巢湖市| 小金县|