Integer和int相比较

Integer和int相比较

一、 Integer类

在Java中,”万物皆对象“,但是八种基本数据类型是个例外,出于性能等方面的考虑,八种基本数据类型没有类和对象的概念,相应的变量值直接在栈内存中存放。但这带来了一些问题,特别是对于集合类的使用,使用集合类时要求泛型必须是类类型,因此,引入了Integer类。Integer是Java中的一个封装类,用于表示整数。它是int的封装类,可以将int类型的数据转换为Integer类型的数据。

有以下三种方法实例化Integer对象:

1.1 构造函数

new Integer(int value)

构造函数,用于实例化一个Integer类的对象。与普通类通过new实例化对象的过程相同,声明的对象引用存放在栈中,该对象引用指向堆中的某块内存区域,该内存区域存放new出的具体数据。比如执行完语句Integer i1 = new Integer(123); 后,栈以及堆中的内存将按以下方式分配:

通过new实例化Integer对象

注意:

从Java9之后,该构造函数已经被废弃,因此对于Java9及其之后的版本不能再使用构造函数实例化Integer对象。

1.2 静态方法

Integer.valueOf(int i)

静态方法,返回指定值的Integer对象,推荐使用该方法实例化Integer对象。下面是该方法的具体实现:

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

IntegerCache.cache是一个用于存放Integer对象的数组,该数组用于缓存区间[IntegerCache.low, IntegerCache.high]内的整数。当通过静态方法valueOf(i)实例化Integer对象时:

  • 若 i∈[IntegerCache.low, IntegerCache.high],直接从数组IntegerCache.cache中取对象以节省内存空间(这也是推荐使用该方法实例化Integer对象的重要原因)
  • 若 i∉[IntegerCache.low, IntegerCache.high],通过构造函数实例化一个新的对象
  • [IntegerCache.low, IntegerCache.high]的默认值为**[-128, 127]**
  • IntegerCache.high的值可以通过 -XX:AutoBoxCacheMax 设置,IntegerCache.high = max(127, -XX:AutoBoxCacheMax)

比如:

public class Main {
    public static void main(String[] args) {
        Integer i1 = Integer.valueOf(127);
        Integer i2 = Integer.valueOf(127);

        Integer i3 = Integer.valueOf(130);
        Integer i4 = Integer.valueOf(130);
    }
}

对于上面这段代码,栈以及堆中的内存将按以下方式分配:

通过静态方法实例化Integer对象

1.3 直接赋值

Integer i1 = 127;

这种方法适用于JDK 1.5及以后的版本,JDK 1.5增加了自动装箱、拆箱的功能,JVM可以完成基本类型和它们对应的包装类之间的自动转换(但并不意味着可以通过基本类型调用它们的包装类才具有的方法),上述代码等价于:

Integer i1 = Integer.valueOf(127);

二、 Integer对象之间的比较

对象之间的比较有两种方式:

  • == :比较两个对象指向的内存区域是否一致

  • equals():Integer对equals()方法进行了重写,比较对象的整数值是否相等

    // Integer 类对 equals 方法进行了重写
    public boolean equals(Object obj) {
        if (obj instanceof Integer) {
            return value == ((Integer)obj).intValue();
        }
        return false;
    }
    

对于下面代码:

public class Main {
    public static void main(String[] args) {
        Integer i1 = Integer.valueOf(127);
        Integer i2 = Integer.valueOf(127);
        Integer i3 = 127; // 等价于 Integer.valueOf(127);
        System.out.println(i1 == i2); // true
        System.out.println(i1 == i3); // true
        System.out.println(i1.equals(i2)); // true

        Integer i4 = Integer.valueOf(130);
        Integer i5 = Integer.valueOf(130);
        Integer i6 = 130; // 等价于 Integer.valueOf(130);
        System.out.println(i4 == i5); // false
        System.out.println(i4 == i6); // false
        System.out.println(i4.equals(i5)); // true

        Integer i7 = new Integer(1); // 只适用于JDK8及之前的版本
        Integer i8 = new Integer(1);
        System.out.println(i7 == i8); // false
        System.out.println(i7.equals(i8)); // true
    }
}

栈以及堆中的内存将按以下方式分配:
Integer对象之间的比较

  • i1、i2、i3都是通过静态方法Integer.valueOf得到的Integer对象,由于值127在区间[-128, 127]内,所以得到的都是同一个存放在IntegerCache.cache数组中的对象,即i1、i2、i3指向的内存区域相同,因此相互使用’=='比较时结果为true。而’equals()'比较的是存放在对象中的整数,因此相互使用’equals()'比较时结果为true。
  • i4、i5、i6也都是通过静态方法Integer.valueOf得到的Integer对象,但值130不在区间[-128, 127]内,所以得到的都是分别通过构造函数new出的对象,即i4、i5、i6指向的内存区域不同,因此相互使用’=='比较时结果为false。而’equals()'比较的是存放在对象中的整数,因此相互使用’equals()'比较时结果为true。
  • i7、i8都是通过构造函数new出的Integer对象,即i7、i8指向的内存区域不同,因此相互使用’=='比较时结果为false。而’equals()'比较的是存放在对象中的整数,因此相互使用’equals()'比较时结果为true。

三、 Integer对象和整型变量之间的比较

  • 当使用 == 比较时。无论是通过何种方式实例化的,Integer对象都会自动拆箱为基本类型,然后再去与整型变量比较。因此,Integer对象和整型变量之间的比较就相当于整数值之间的比较,只要整数值相同结果即为true。
  • 当Integer对象使用equals()方法与整型变量比较时。整型变量会自动装箱成Integer对象,然后通过equals()方法比较对象所存的整数值是否相同。
  • 综上,无论使用哪种方式,Integer对象和整型变量之间的比较都是Integer对象所存的整数值和整型变量之间的比较

比如:

public class Main {
    public static void main(String[] args) {
        int i1 = 127;
        Integer i2 = 127;
        Integer i3 = Integer.valueOf(127);
        Integer i4 = new Integer(127); // 只适用于JDK8及之前的版本

        System.out.println(i1 == i2); // true
        System.out.println(i1 == i3); // true
        System.out.println(i1 == i4); // true
        System.out.println(i2.equals(i1)); // true


        int i5 = 130;
        Integer i6 = 130;
        Integer i7 = Integer.valueOf(130);
        Integer i8 = new Integer(130); // 只适用于JDK8及之前的版本

        System.out.println(i5 == i6); // true
        System.out.println(i5== i7); // true
        System.out.println(i5 == i8); // true
        System.out.println(i6.equals(i5)); // true
    }
}

注:

各包装类缓存值范围(默认) :

  • boolean:true、false
  • byte:-128~127
  • char:0~127
  • short:-128~127
  • int:-128~127
  • long:-128~127
  • float和double:无缓存
  • 22
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值