一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Java Integer對象的比較方式

Java Integer對象的比較方式

2022-01-10 00:59bsbhenry Java教程

這篇文章主要介紹了Java Integer對象的比較方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

Java Integer對象的比較

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

自動裝箱

Integer是一種對象包裝器類。對象包裝器類是不可變的,也就是說,一旦完成了構造,包裝在其中的值就不可以再被更改了。包裝器類有一種特性,自動裝箱。當需要一個Integer類型的對象時,可以對int類型的元素進行自動打包的操作。如果添加3到list中,實際調用的是下面的代碼。

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

valueOf的源代碼如下

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

其中IntegerCache定義如下

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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會維護一個Integer的數組,將值在某個范圍內(默認-128~127)的對象緩存起來,在這個范圍內的int會被包裝到固定的對象中,valueOf會返回緩存中的對象。如果不在這個范圍內,則會創建一個新的對象。注意,使用new創建的新對象是在堆中的,這一點會影響到Integer對象之間的比較結果。

自動拆箱

與自動裝箱對應的,存在自動拆箱操作。當將一個Integer對象賦值給一個int值時,編譯器就會插入對象拆箱指令。

?
1
2
int n = list.get(i);
int n = list.get(i).intValue();

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

?
1
2
3
public int intValue() {
    return value;
}

Integer初始化

1.初始化Integer的時候,可以直接用一個int值賦值,實際上會自動裝箱。

?
1
2
Integer n1 = 3;
Integer n1 = Integer.valueOf(3);

2.當然也可以使用new來創建Integer對象.

?
1
Integer n2 = new Integer(3);

Integer對象之間的比較

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

==運算符

如果使用==運算符進行比較的話,由于檢測的是對象是否指向同一個內存區域,由于初始化時的不確定性,比較的結果也可能不是我們想要的。如下所示:

?
1
2
3
4
5
6
7
8
9
10
11
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,兩個new的對象
System.out.println(n1 == n3);   //false  n1在堆中,n3指向IntegerCache緩存(方法區中)
System.out.println(n3 == n4);   //true   都指向緩存中同一個對象
System.out.println(n5 == n6);   //false  超出緩存范圍,分別是兩個new出來的對象

equals

所以為了保持對象之間比較結果的一致性,同時我們進行比較的初衷應該也是比較它們之間的值,所以使用equals方法

?
1
2
3
4
5
6
public boolean equals(Object obj) {
    if (obj instanceof Integer) {
        return value == ((Integer)obj).intValue();
    }
    return false;
}

Integer類重寫了object的equals方法,調用時實際比較的是兩個對象的值,和對象存儲在哪里沒有關系。

Integer類型變量比較問題

今天在做實驗的時候,發現了一個比較奇怪的問題:兩個Integer型變量用==進行比較時,有時候能成功有時候不能成功。舉個例子:

代碼1

?
1
2
3
4
5
6
Integer l1 = 122;
Integer l2 = 122;
if(l1 == l2)
    System.out.println("Right");
else
    System.out.println("Wrong");

  

運行這段代碼時,程序會輸出:Right。對于另一個例子:

代碼2

?
1
2
3
4
5
6
Integer l1 = 233;
Integer l2 = 233;
if(l1 == l2)
    System.out.println("Right");
else
    System.out.println("Wrong");

  

運行這段代碼時,程序會輸出Wrong。但當對代碼2進行修改時:

代碼3

?
1
2
3
4
5
6
Integer l1 = 233;
int l2 = 233;
if(l1 == l2)
    System.out.println("Right");
else
    System.out.println("Wrong");

在運行這段代碼時,程序會輸出Right。如果換一種定義方式時:

代碼4

?
1
2
3
4
5
6
Integer l1 = 233;
Integer l2 = new Integer(233);
if(l1 == l2)
    System.out.println("Right");
else
    System.out.println("Wrong");

運行這段代碼時,程序會輸出Wrong。

關于這種現象,查了下資料,總結如下

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

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

?
1
2
3
4
5
6
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);
     }

看一下源碼就會明白,對于-128到127之間的數,會進行緩存,Integer l1 = 122時,會將122進行緩存,下次再寫Integer l2 = 122時,就會直接從緩存中取,就不會new了,相當于生成的為同一個對象,。所以代碼1的運行結果是Right。

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

2.對于代碼3,Integer型變量與int型變量進行比較時,實質上是把Integer類型變量拆箱成int類型,然后進行比較,相等則返回true,否則返回false。此處的拆箱調用的是intValue()方法。所以代碼3的運行結果是Right。

3.對于代碼4,就比較好解釋了,因為new相當于重新定義了一個新的對象,即l1的引用實質是指向在堆中了,而l2實質是指向在常量池中了,所以兩者是不可能相等的,故輸出結果就是Wrong。

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

5.Integer型變量與int型變量之間可以直接比較,此時自動進行拆箱操作。

以上為個人經驗,希望能給大家一個參考,也希望大家多多支持服務器之家。

原文鏈接:https://blog.csdn.net/bsbhenry/article/details/90743619

延伸 · 閱讀

精彩推薦
  • Java教程小米推送Java代碼

    小米推送Java代碼

    今天小編就為大家分享一篇關于小米推送Java代碼,小編覺得內容挺不錯的,現在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧...

    富貴穩中求8032021-07-12
  • Java教程20個非常實用的Java程序代碼片段

    20個非常實用的Java程序代碼片段

    這篇文章主要為大家分享了20個非常實用的Java程序片段,對java開發項目有所幫助,感興趣的小伙伴們可以參考一下 ...

    lijiao5352020-04-06
  • Java教程Java BufferWriter寫文件寫不進去或缺失數據的解決

    Java BufferWriter寫文件寫不進去或缺失數據的解決

    這篇文章主要介紹了Java BufferWriter寫文件寫不進去或缺失數據的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望...

    spcoder14552021-10-18
  • Java教程Java8中Stream使用的一個注意事項

    Java8中Stream使用的一個注意事項

    最近在工作中發現了對于集合操作轉換的神器,java8新特性 stream,但在使用中遇到了一個非常重要的注意點,所以這篇文章主要給大家介紹了關于Java8中S...

    阿杜7482021-02-04
  • Java教程升級IDEA后Lombok不能使用的解決方法

    升級IDEA后Lombok不能使用的解決方法

    最近看到提示IDEA提示升級,尋思已經有好久沒有升過級了。升級完畢重啟之后,突然發現好多錯誤,本文就來介紹一下如何解決,感興趣的可以了解一下...

    程序猿DD9332021-10-08
  • Java教程Java實現搶紅包功能

    Java實現搶紅包功能

    這篇文章主要為大家詳細介紹了Java實現搶紅包功能,采用多線程模擬多人同時搶紅包,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙...

    littleschemer13532021-05-16
  • Java教程Java使用SAX解析xml的示例

    Java使用SAX解析xml的示例

    這篇文章主要介紹了Java使用SAX解析xml的示例,幫助大家更好的理解和學習使用Java,感興趣的朋友可以了解下...

    大行者10067412021-08-30
  • Java教程xml與Java對象的轉換詳解

    xml與Java對象的轉換詳解

    這篇文章主要介紹了xml與Java對象的轉換詳解的相關資料,需要的朋友可以參考下...

    Java教程網2942020-09-17
主站蜘蛛池模板: 欧美日韩一区二区三区久久 | 99久久综合久中文字幕 | 鄂州一家三口完整版免费 | 国产成人一级 | 亚洲欧美日韩国产精品一区 | 国内永久第一免费福利视频 | 国产欧美二区三区 | 日日摸夜夜爽色婷婷91 | 国产特黄一级一片免费 | 国产精品调教 | 亚洲毛片基地4455ww | 免费看一级 | 久久成人精品免费播放 | 亚州春色 | 婷婷久久综合九色综合九七 | 欧美成人v视频免费看 | 国产一区二区三区免费在线视频 | 国产精品青青青高清在线 | 加勒比一本大道香蕉在线视频 | 万域之王动漫在线观看全集免费播放 | 好涨好大我快受不了了视频网 | 女暴露狂校园裸露小说 | 狠狠香蕉| 视频免费视频观看网站 | 日本sss在线高清观看 | 国产亚洲小视频 | 国色天香社区视频免费观看3 | 欧美日韩一区二区三区在线视频 | 深夜激情网 | 猫咪色网 | 91精品国产高清久久久久久91 | 草大逼 | 久久精品123 | 插入逼 | 亚洲精品视频观看 | 亚欧美色| 精品久久久噜噜噜久久7 | 99热久久这里只精品国产www | 91影视在线看免费观看 | 青青色综合 | 4hc44四虎www在线影院男同 |