自動包裝機制Integer,與AtomicReference 的問題


從如下代碼開始了解Integer的自動包裝機制

 1 import java.util.concurrent.atomic.AtomicInteger;
 2 import java.util.concurrent.atomic.AtomicReference;
 3 
 4 /**
 5  * 比較方法一與方法二的區別
 6  */
 7 public class AtomicIntegerDemo {
 8 
 9     static void demo1(){
10         AtomicInteger atomicInteger = new AtomicInteger(100);
11         atomicInteger.compareAndSet(100, 200);
12         atomicInteger.compareAndSet(200, 400);
13         System.out.println(atomicInteger.get());
14     }
15 
16     /**
17      * 需要仔細了解此例輸出
18      */
19     static void demo2(){
20         AtomicReference<Integer> atomicReference = new AtomicReference<>(100);
21         atomicReference.compareAndSet(100, 200);
22         atomicReference.compareAndSet(200, 400); 23         System.out.println(atomicReference.get());
24     }
25     
26     public static void main(String[] args) {
27         demo1();
28         demo2();
29     }
30 }

此代碼的輸出如下:

400
200

Process finished with exit code 0

預期demo2()方法最終輸出400,但結果並不是。

問題根源,自動包裝機制:

 1 public final class Integer extends Number implements Comparable<Integer> {
 2     /**
 3      * The value of the {@code Integer}.
 4      *
 5      * @serial
 6      */
 7     private final int value;
 8 
 9     /**
10      * Returns an {@code Integer} instance representing the specified
11      * {@code int} value.  If a new {@code Integer} instance is not
12      * required, this method should generally be used in preference to
13      * the constructor {@link #Integer(int)}, as this method is likely
14      * to yield significantly better space and time performance by
15      * caching frequently requested values.
16      *
17      * This method will always cache values in the range -128 to 127,
18      * inclusive, and may cache other values outside of this range.
19      *
20      * @param  i an {@code int} value.
21      * @return an {@code Integer} instance representing {@code i}.
22      * @since  1.5
23      */
24     public static Integer valueOf(int i) { 25         if (i >= IntegerCache.low && i <= IntegerCache.high) 26             return IntegerCache.cache[i + (-IntegerCache.low)]; 27         return new Integer(i); 28  } 29     /**
30      * Cache to support the object identity semantics of autoboxing for values between
31      * -128 and 127 (inclusive) as required by JLS.
32      *
33      * The cache is initialized on first usage.  The size of the cache
34      * may be controlled by the {@code -XX:AutoBoxCacheMax=<size>} option.
35      * During VM initialization, java.lang.Integer.IntegerCache.high property
36      * may be set and saved in the private system properties in the
37      * sun.misc.VM class.
38      */
39 
40     private static class IntegerCache {
41         static final int low = -128;
42         static final int high;
43         static final Integer cache[];
44         . . .
45     }
46 . . .
47 }

AtomicReference中對象的比較為地址的比較。對於int字面量java會進行裝箱將其轉換成Integer對象,調用的是Integer.valueOf方法, 看源碼你就明白了,128以內的會使用緩存,同一個int字面量返回同一個對象用==比較為true,而超過128返回不是同一個對象,==為false,equal才是true。

 

本文結束。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM