栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java int 和 Integer 互转原理

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java int 和 Integer 互转原理

Java int 和 Integer 互转

documentation

Autoboxing is the automatic conversion that the Java compiler makes between the primitive types and their corresponding object wrapper classes. For example, converting an int to an Integer, a double to a Double, and so on. If the conversion goes the other way, this is called unboxing.

自动装箱(拆箱也是)是 Java 编译器提供的原始类型和它的包装类之间转化的功能。
注意,自动装箱和拆箱是 Java 编译器的功能,并不是运行时的。

int 转 Integer:

List li = new ArrayList<>();
for (int i = 1; i < 50; i += 2)
    li.add(i);

// Java 编译器把上面的代码转换成了下面的样子
List li = new ArrayList<>();
for (int i = 1; i < 50; i += 2)
    li.add(Integer.valueOf(i));

反过来,Integer 转 int:

public static int sumEven(List li) {
    int sum = 0;
    for (Integer i: li)
        if (i % 2 == 0)
            sum += i;
   return sum;
}
// 编译器把上面的代码转化成了下面的样子
public static int sumEven(List li) {
    int sum = 0;
    for (Integer i : li)
        if (i.intValue() % 2 == 0)
            sum += i.intValue();
        return sum;
}

Java 中 int 和I nteger 互转,原理是 Java 编译器帮你调用了包装类的 valueOf() 和 intValue() 两个方法。

Java Integer、int 与 new Integer()

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

对于 Integer var = ? 在 -128 至 127 范围内的赋值,Integer 对象是在 IntegerCache.cache 产生,会复用已有对象,这个区间内的 Integer 值可以直接使用 == 进行判断,但是这个区间之外的所有数据,都会在堆上产生,并不会复用已有对象,所以推荐使用 equals 方法进行判断。

  1. int 和 Integer 在进行比较的时候,Integer 会进行拆箱,转为 int 值与 int 进行比较。
  2. Integer 与 Integer 比较的时候,由于直接赋值的时候会进行自动的装箱。

IntegerCache 为 Integer 类的缓存类,默认缓存了 -128~127 的 Integer 值,如遇到 [-128,127] 范围的值需要转换为 Integer 时会直接从 IntegerCache 中获取,具体如以下源码:

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

当大于这个范围的时候,直接 new Integer 来创建 Integer 对象。

new Integer(1) 和 Integer a = 1 ,前者创建对象,存储在堆中,而后者是从 IntegerCache 中获取的。那么 Integer a = 128, 直接通过 new Integer(128)创建对象,进行装箱。

public class Test { 
	public static void main(String[] args) {
		
		Integer i = new Integer(128);
		Integer i2 = 128; // 自动装箱
		// == 比较对象的地址是不是相同
		System.out.println(i == i2); // false
		
		Integer i3 = new Integer(127);
		Integer i4 = 127;
		System.out.println(i3 == i4);  // false
		
		Integer i5 = 128;
		Integer i6 = 128;
		System.out.println(i5 == i6);  // false
		
		Integer i7 = 127;
		Integer i8 = 127;
		System.out.println(i7 == i8); // true
	}
}
Integer.valueOf() new Integer()

当你需要产生一个整形的包装类的实例的时候(比如整数10),有两种方式:
第一种,使用构造函数 new 一个对象:

Integer i = new Integer(10);// 已过时,且标记为待删除。

第二种,使用静态工厂方法产生实例:

Integer i = Integer.valueOf(10);

当你用第一种方式时每次都会产生一个新的实例,而当你使用静态工厂方法时,不一定会产生一个新的实例,注意我说的是不一定,至少这里没有产生一个新的实例。

当你产生的数是 -128 到127时,不会 new 一个新的对象,超过这个范围时,同样是 new 一个新的对象。

为什么 Java 9 不建议使用 new Integer 了?

java.lang.Integer @Deprecated(since = “9”)
@Contract(pure = true)

It is rarely appropriate to use this constructor. The static factory valueOf(int) is generally a better choice, as it is likely to yield significantly better space and time performance.

最后一句不说说了吗,有更好的空间和时间性能,你用new 也没事。

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

上面是 valueOf, 当你传入小于 128 的值时,返回的是内置的缓存值,节省空间和效率。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/681753.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号