欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java Integer對(duì)象的比較方式

 更新時(shí)間:2021年09月18日 08:37:27   作者:bsbhenry  
這篇文章主要介紹了Java Integer對(duì)象的比較方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

Java Integer對(duì)象的比較

Integer對(duì)象之間的比較要考慮到對(duì)象初始化的不同情況,初始化又涉及到對(duì)象包裝器類的自動(dòng)裝箱特性 。

自動(dòng)裝箱

Integer是一種對(duì)象包裝器類。對(duì)象包裝器類是不可變的,也就是說,一旦完成了構(gòu)造,包裝在其中的值就不可以再被更改了。包裝器類有一種特性,自動(dòng)裝箱。當(dāng)需要一個(gè)Integer類型的對(duì)象時(shí),可以對(duì)int類型的元素進(jìn)行自動(dòng)打包的操作。如果添加3到list中,實(shí)際調(diào)用的是下面的代碼。

ArrayList<Integer> list = new ArrayList(); 
list.add(3);
list.add(Integer.valueOf(3));

valueOf的源代碼如下

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

其中IntegerCache定義如下

 private static class IntegerCache {
        static final int low = -128;
        static final int high;
        static final Integer cache[]; 
        static {
            // high value may be configured by property
            int h = 127;
            String integerCacheHighPropValue =
                VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
            if (integerCacheHighPropValue != null) {
                try {
                    int i = parseInt(integerCacheHighPropValue);
                    i = Math.max(i, 127);
                    // Maximum array size is Integer.MAX_VALUE
                    h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
                } catch( NumberFormatException nfe) {
                    // If the property cannot be parsed into an int, ignore it.
                }
            }
            high = h;
 
            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);
 
            // range [-128, 127] must be interned (JLS7 5.1.7)
            assert IntegerCache.high >= 127;
        }
 
        private IntegerCache() {}
    }

JVM會(huì)維護(hù)一個(gè)Integer的數(shù)組,將值在某個(gè)范圍內(nèi)(默認(rèn)-128~127)的對(duì)象緩存起來,在這個(gè)范圍內(nèi)的int會(huì)被包裝到固定的對(duì)象中,valueOf會(huì)返回緩存中的對(duì)象。如果不在這個(gè)范圍內(nèi),則會(huì)創(chuàng)建一個(gè)新的對(duì)象。注意,使用new創(chuàng)建的新對(duì)象是在堆中的,這一點(diǎn)會(huì)影響到Integer對(duì)象之間的比較結(jié)果。

自動(dòng)拆箱

與自動(dòng)裝箱對(duì)應(yīng)的,存在自動(dòng)拆箱操作。當(dāng)將一個(gè)Integer對(duì)象賦值給一個(gè)int值時(shí),編譯器就會(huì)插入對(duì)象拆箱指令。

int n = list.get(i);
int n = list.get(i).intValue();

intvalue()源代碼就很簡(jiǎn)單了,返回對(duì)象的value屬性

    public int intValue() {
        return value;
    }

Integer初始化

1.初始化Integer的時(shí)候,可以直接用一個(gè)int值賦值,實(shí)際上會(huì)自動(dòng)裝箱。

Integer n1 = 3;
Integer n1 = Integer.valueOf(3);

2.當(dāng)然也可以使用new來創(chuàng)建Integer對(duì)象.

Integer n2 = new Integer(3);

Integer對(duì)象之間的比較

由于IntegerCache的存在,使用第一種方法初始化的對(duì)象,如果值的范圍在-128~127之間,則相同的值會(huì)被包裝的同一對(duì)象中。而用new產(chǎn)生的對(duì)象肯定不會(huì)在同一內(nèi)存區(qū)域。

==運(yùn)算符

如果使用==運(yùn)算符進(jìn)行比較的話,由于檢測(cè)的是對(duì)象是否指向同一個(gè)內(nèi)存區(qū)域,由于初始化時(shí)的不確定性,比較的結(jié)果也可能不是我們想要的。如下所示:

        Integer n1 = new Integer(47);
        Integer n2 = new Integer(47);
        Integer n3 = 47;
        Integer n4 = 47;
        Integer n5 = 200;
        Integer n6 = 200;
 
        System.out.println(n1 == n2);   //false,兩個(gè)new的對(duì)象
        System.out.println(n1 == n3);   //false  n1在堆中,n3指向IntegerCache緩存(方法區(qū)中)
        System.out.println(n3 == n4);   //true   都指向緩存中同一個(gè)對(duì)象
        System.out.println(n5 == n6);   //false  超出緩存范圍,分別是兩個(gè)new出來的對(duì)象

equals

所以為了保持對(duì)象之間比較結(jié)果的一致性,同時(shí)我們進(jìn)行比較的初衷應(yīng)該也是比較它們之間的值,所以使用equals方法

    public boolean equals(Object obj) {
        if (obj instanceof Integer) {
            return value == ((Integer)obj).intValue();
        }
        return false;
    }

Integer類重寫了object的equals方法,調(diào)用時(shí)實(shí)際比較的是兩個(gè)對(duì)象的值,和對(duì)象存儲(chǔ)在哪里沒有關(guān)系。

Integer類型變量比較問題

今天在做實(shí)驗(yàn)的時(shí)候,發(fā)現(xiàn)了一個(gè)比較奇怪的問題:兩個(gè)Integer型變量用==進(jìn)行比較時(shí),有時(shí)候能成功有時(shí)候不能成功。舉個(gè)例子:

代碼1

Integer l1 = 122;
Integer l2 = 122;
if(l1 == l2)
    System.out.println("Right");
else
    System.out.println("Wrong");

  

運(yùn)行這段代碼時(shí),程序會(huì)輸出:Right。對(duì)于另一個(gè)例子:

代碼2

Integer l1 = 233;
Integer l2 = 233;
if(l1 == l2)
    System.out.println("Right");
else
    System.out.println("Wrong");

  

運(yùn)行這段代碼時(shí),程序會(huì)輸出Wrong。但當(dāng)對(duì)代碼2進(jìn)行修改時(shí):

代碼3

Integer l1 = 233;
int l2 = 233;
if(l1 == l2)
    System.out.println("Right");
else
    System.out.println("Wrong");

在運(yùn)行這段代碼時(shí),程序會(huì)輸出Right。如果換一種定義方式時(shí):

代碼4

Integer l1 = 233;
Integer l2 = new Integer(233);
if(l1 == l2)
    System.out.println("Right");
else
    System.out.println("Wrong");

運(yùn)行這段代碼時(shí),程序會(huì)輸出Wrong。

關(guān)于這種現(xiàn)象,查了下資料,總結(jié)如下

1.實(shí)際上Java中定義的Integer變量會(huì)通過Integer.valueOf()方法生成一個(gè)實(shí)例,即:

Integer l1 = 122 會(huì)被編譯成 Integer l1 = Integer.valueOf(122),而關(guān)于valueOf()方法的源碼:

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);
     }

看一下源碼就會(huì)明白,對(duì)于-128到127之間的數(shù),會(huì)進(jìn)行緩存,Integer l1 = 122時(shí),會(huì)將122進(jìn)行緩存,下次再寫Integer l2 = 122時(shí),就會(huì)直接從緩存中取,就不會(huì)new了,相當(dāng)于生成的為同一個(gè)對(duì)象,。所以代碼1的運(yùn)行結(jié)果是Right。

而對(duì)于這個(gè)范圍之外的數(shù)值,valueOf()相會(huì)重新new一個(gè)對(duì)象,所以就不相等了,所以代碼2的裕興結(jié)果就是Wrong。

2.對(duì)于代碼3,Integer型變量與int型變量進(jìn)行比較時(shí),實(shí)質(zhì)上是把Integer類型變量拆箱成int類型,然后進(jìn)行比較,相等則返回true,否則返回false。此處的拆箱調(diào)用的是intValue()方法。所以代碼3的運(yùn)行結(jié)果是Right。

3.對(duì)于代碼4,就比較好解釋了,因?yàn)閚ew相當(dāng)于重新定義了一個(gè)新的對(duì)象,即l1的引用實(shí)質(zhì)是指向在堆中了,而l2實(shí)質(zhì)是指向在常量池中了,所以兩者是不可能相等的,故輸出結(jié)果就是Wrong。

4.總之,要想比較兩個(gè)Intger型變量的值最好用Integer.intValue()方法生成int型后再比較。

5.Integer型變量與int型變量之間可以直接比較,此時(shí)自動(dòng)進(jìn)行拆箱操作。

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • JDBC 使用說明(流程、架構(gòu)、編程)

    JDBC 使用說明(流程、架構(gòu)、編程)

    這篇文章主要介紹了JDBC 使用說明,需要的朋友可以參考下
    2015-08-08
  • java多態(tài)中的就近原則介紹

    java多態(tài)中的就近原則介紹

    大家好,本篇文章主要講的是java多態(tài)中的就近原則介紹,感興趣的同學(xué)趕快來看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽
    2021-12-12
  • SpringBoot使用ApplicationEvent&Listener完成業(yè)務(wù)解耦

    SpringBoot使用ApplicationEvent&Listener完成業(yè)務(wù)解耦

    這篇文章主要介紹了SpringBoot使用ApplicationEvent&Listener完成業(yè)務(wù)解耦示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-05-05
  • Java23種設(shè)計(jì)模式中的單例模式你了解嗎

    Java23種設(shè)計(jì)模式中的單例模式你了解嗎

    這篇文章主要為大家詳細(xì)介紹了Java23種設(shè)計(jì)模式中的單例模式,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-02-02
  • Java 照片對(duì)比功能的實(shí)現(xiàn)

    Java 照片對(duì)比功能的實(shí)現(xiàn)

    這篇文章主要介紹了Java 照片比對(duì)功能實(shí)現(xiàn)類的示例代碼,幫助大家更好的理解和學(xué)習(xí)Java,感興趣的朋友可以了解下
    2020-12-12
  • Java的MybatisPlus詳解

    Java的MybatisPlus詳解

    這篇文章主要介紹了Java的MybatisPlus詳解,MyBatis-Plus是一個(gè) MyBatis的增強(qiáng)工具,在MyBatis的基礎(chǔ)上只做增強(qiáng)不做改變,為簡(jiǎn)化開發(fā)、提高效率而生,需要的朋友可以參考下
    2023-07-07
  • Bean實(shí)例化之前修改BeanDefinition示例詳解

    Bean實(shí)例化之前修改BeanDefinition示例詳解

    這篇文章主要為大家介紹了Bean實(shí)例化之前修改BeanDefinition示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • Java中Word與PDF轉(zhuǎn)換為圖片的方法詳解

    Java中Word與PDF轉(zhuǎn)換為圖片的方法詳解

    這篇文章主要為大家詳細(xì)介紹了如何使用Java實(shí)現(xiàn)將Word與PDF轉(zhuǎn)換為圖片,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-10-10
  • springmvc?html資源請(qǐng)求404的問題解決并分析

    springmvc?html資源請(qǐng)求404的問題解決并分析

    這篇文章主要介紹了springmvc?html資源請(qǐng)求404的問題解決并分析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • mybatis主從表關(guān)聯(lián)查詢,返回對(duì)象帶有集合屬性解析

    mybatis主從表關(guān)聯(lián)查詢,返回對(duì)象帶有集合屬性解析

    這篇文章主要介紹了mybatis主從表關(guān)聯(lián)查詢,返回對(duì)象帶有集合屬性解析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03

最新評(píng)論