日期:2014-05-20  浏览次数:20784 次

Java 自动装箱的疑惑
《深入理解Java虚拟机》中的阐述Java语法糖的有关自动装箱的例子如下:

public class AutoPack {

public static void main(String[] args) {
// TODO Auto-generated method stub
Integer a=1;
Integer b=2;
Integer c=3;
Integer d=3;
Integer e=321;
Integer f=321;
Long g=3L;
System.out.println("c==d is:"+(c==d));
System.out.println("e==f is:"+(e==f));
System.out.println("c==(a+b)d is:"+(c==(a+b)));
System.out.println("c.equals(a+b) is:"+(c.equals(a+b)));
System.out.println("g==(a+b) is:"+(g==(a+b)));
System.out.println("g.equals(a+b) is:"+(g.equals(a+b)));

}

}


输出结果如下:
c==d is:true
e==f is:false
c==(a+b)d is:true
c.equals(a+b) is:true
g==(a+b) is:true
g.equals(a+b) is:false

疑问主要有两点:
1.c==d和e==f无论类型还是数值应该都是一样的,为什么c==d返回的是true,而e==f返回的false?
2c.equals(a+b)和g.equals(a+b)的自动装箱是怎么样的,和1有同样的疑问,返回的结果为什么是不同的?


------解决方案--------------------
Integer -128 到127 是提前建好的,所以当你新建的值在这范围内就是直接引用这个建好的对象。所以c和d其实指向同一个内存地址。e和f就不是同一地址,而是新建的。
------解决方案--------------------
equals 是值比较,但只能用作同类型的object作比较。 所以你Long 对比Integer就相当于对比null。然后就false。
------解决方案--------------------
整型的范围我记得是-127-128吧,321超出这个范围会怎么样呢,建新的呗。 新的就指向了不同的地址,当然比较就不一样了。
------解决方案--------------------
 /**
     * Cache to support the object identity semantics of autoboxing for values between 
     * -128 and 127 (inclusive) as required by JLS.
     *
     * The cache is initialized on first usage. During VM initialization the
     * getAndRemoveCacheProperties method may be used to get and remove any system
     * properites that configure the cache size. At this time, the size of the
     * cache may be controlled by the vm option -XX:AutoBoxCacheMax=<size>.
     */

    // value of java.lang.Integer.IntegerCache.high property (obtained during VM init)
    private static String integerCacheHighPropValue;

------解决方案--------------------
考点就是-128到127以外的数,new的内存地址是不一样的