integer比较_Java中的整型包装类值的比较为什么不能用==比较?原因是因为缓存

我们可能从书上能看到,所有整型包装类对象之间值的比较,全部使用equals进行比较,那么为什么不能用 "==" 比较呢?我们先看下面的例子。

Example1:

public class Demo3 {    public static void main( String[] args ) {        Integer a = 2;        Integer b = 2;        System.out.println(a == b);//保存的是地址    }}

Example2:

public class Demo3 {    public static void main( String[] args ) {        Integer a = 222;        Integer b = 222;        System.out.println(a == b);//保存的是地址    }}

通过测试Example1 的结果为 True;

Example2的结果为false;

那么为什么呢?

下面先看下字节码:

39dc3f5f959749d4a268ce6fec94d617.png

我们看到划线的部分:

Integer i = 2;会自动装箱,调用Integer.valueOf()方法进行转换。

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

也就是说,如果Integer的范围在 -128~127之间,则调用valueOf方法时,会从缓存中获取。

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() {}    }

那么为什么Example1为true呢?

Integer a = 2;

Integer b = 2;

都是从缓存中获取相同的对象。

那么为什么Example2为false呢?

Integer a = 222;//new Integer(222)

Integer b = 222;//new Integer(222)

a== b 比较的是地址,所以为false;

所以说对Integer 进行值比较时,需要用equals方法

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

分享一个面试题

面试题:

主方法定义两个Integer变量,并赋值

然后通过一个swap方法交换变量的值

请写出swap方法的实现

实现程序如下:

public class Demo {    //java中的传值方式  按值传递  引用传递    public static void main( String[] args ) {        Integer a = 1;//装箱 Interger.valueof()        Integer b = 2;        System.out.println("Before swap:a="+a+",b="+b);        //把 a,b 的值进行交换        swap(a,b);        System.out.println("After swap:a="+a+",b="+b);    }    private static void swap( Integer a, Integer b ) {        Integer tmp = a;        a = b;        b= tmp;    }}

结果:

Before swap:a=1,b=2After swap:a=1,b=2

为什么没有改变呢?因为用的是值传递,图示如下:

1、初始状态

aff999e79ee0726700c314a2e26ac79b.png

2.交换过后

2418e5b77ba8226b9fd3a2620c1ca5f3.png

所以swap方式只是改变了 num1和 num2的引用,并没有改变 a 和 b 的引用。

那么怎么实现 才是正确的呢?通过反射

   private static void swap( Integer a, Integer b ) {        try {           Field field =  Integer.class.getDeclaredField("value");            field.setAccessible(true);           int tmp = a.intValue();           // 获取b的值,调用valueof           field.set(a,b);//取b的值,走valueOf           field.set(b,new Integer(tmp));        } catch (Exception e) {            e.printStackTrace();        }    }

总结

所有整型包装类对象之间值的比较,全部使用 equals 方法比较。

说明:对于 Integer var = ? 在-128 至 127 之间的赋值,Integer 对象是在 IntegerCache.cache 产生,

会复用已有对象,这个区间内的 Integer 值可以直接使用==进行判断,但是这个区间之外的所有数据,都会在堆上产生,并不会复用已有对象,这是一个大坑,推荐使用 equals 方法进行判断

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值