java中自动拆箱和装箱的小细节

ps:个人能力有限,如有不对请指出

1、#### 版本要求 ###
jdk1.5才支持自动装箱和自动拆箱
Java的面向对象思想一般采用对象来操作数据,在操作基本数据类型是采用的是值传递方式,而对对象采用的是引用传递的方式。
基本有byte(8位),short(16位),int(32位),long(64位),float(32位),double(64位),boolean(未知)

数据类型传递方式
基本数据类型值传递
引用类型引用传递

下面一个简单的例子说明一下值传递和引用传递的区别:

public class Test20170412 {
    public static void main(String[] args) {
      int i=1;
      Demo d =new Demo(20);
      display(i, d);
      System.out.println("i="+i+" d中a的值"+d.get());
      Integer in = new Integer(i);
      display(in, d);
      System.out.println("i="+in+" d中a的值"+d.get());
    }
    public static void display(int i,Demo d){
        i=i+1;
        d.set();
    }
    public static void display(Integer i,Demo d){
        i=new Integer(100);
        d.set();
    }

}
class Demo{
    private int a;
    Demo(int value){
        a=value;
    }
    public void set(){
        a=100;
    }
    public int get(){
        return a;
    }
}

输出结果:
i=1 d中a的值100
i=1 d中a的值100
结果i的值并没有被改变,就算重载display() 也不行,看来已经进行了自动拆箱的操作了
一般情况下的Integer对象和int之间的比较

      int a =100;
      Integer b = new Integer(100);
      Integer c = new Integer(100);
      System.out.println(a==b);
      System.out.println(b==c);

结果:
true
false
第一个对,b进行了自动拆箱,拆成100 ,100==100没毛病;
第二个错,因为对象比较的是两个对象的地址,在内存中不一样,所以错误
最后看一看bc的hashcode(),发现都为100,可以说明的是hashcode相同,两个对象不一定相同,从源码上来看Integer重写hashcode,返回的是value,就是构造方法传入值。

 @Override
    public int hashCode() {
        return Integer.hashCode(value);
    }

下面要说的是Intger的缓冲区,先由一个例子来看



public class SetandUnzip {
    public static void main(String[] args) {
       for(int i=-129;i<200;i++){
           Integer i1= i;
           Integer i2=i;
           System.out.print("位置"+i+" "+(i1==i2)+"\n");
       }
    }

}

输出信息:

位置-129 false
位置-128 true
位置-127 true
位置-126 true
位置-125 true
位置-124 true
位置-123 true
位置-122 true
位置-121 true
位置-120 true
位置-119 true
位置-118 true
位置-117 true
。。。。。。。
位置118 true
位置119 true
位置120 true
位置121 true
位置122 true
位置123 true
位置124 true
位置125 true
位置126 true
位置127 true
位置128 false
位置129 false
位置130 false
位置131 false

在4,5,6行进行断点调试(按f5)可以发现在
用int直接给Integer复制时调用的构造方法是valueof(),返回Integer对象,有结果看说明在-128到127之间是同一个对象因为前面我们说到了,对象相等说明是同一个对象(地址相同的)

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

jdk1.7中对代码断点调试可以看到上面的代码,其中IntegerCache.low=-128,IntegerCache.high=127,顾名思义在Integer类的缓存区,然后在往下细看

 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 =
                sun.misc.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() {}
    }

可以看到IntegerCache是一个内部静态类,有low,high两个变量和静态缓存对象数组cache 。在静态块中创建了缓存对象数组利用静态内部类的特性只会加载一次。
只要在low和high之间且是同一值就会返回同一个对象所以相等
???疑惑???在上面代码中有getSavedProperty应该是可以设置high的值的,但我不知道怎么设置

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值