java包装类型的缓存机制

本文探讨了Java中Integer, Character, Boolean等基本数据类型包装类的缓存机制,详细解析了Integer的缓存源码,并通过实例展示了缓存如何影响对象的相等性判断。对于浮点数类型,如Float和Double,则没有类似的缓存优化。建议在比较整型包装类对象时使用equals方法。此外,还提供了验证缓存效果的代码示例。
摘要由CSDN通过智能技术生成

Java 基本数据类型的包装类型的大部分都用到了缓存机制来提升性能。

Byte,Short,Integer,Long 这 4 种包装类默认创建了数值 [-128,127] 的相应类型的缓存数据,Character 创建了数值在 [0,127] 范围的缓存数据,Boolean 直接返回 True or False

Integer缓存源码:

public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}
private static class IntegerCache {
    static final int low = -128;
    static final int high;
    static {
        // high value may be configured by property
        int h = 127;
    }
}

Character缓存源码:

public static Character valueOf(char c) {
    if (c <= 127) { // must cache
      return CharacterCache.cache[(int)c];
    }
    return new Character(c);
}

private static class CharacterCache {
    private CharacterCache(){}
    static final Character cache[] = new Character[127 + 1];
    static {
        for (int i = 0; i < cache.length; i++)
            cache[i] = new Character((char)i);
    }

}

Boolean源码:

public static Boolean valueOf(boolean b) {
    return (b ? TRUE : FALSE);
}

 如果超出缓存范围仍然会创建新的对象,缓存的区间大小只是在性能和资源之间的权衡。两种浮点数类型的包装类 Float,Double 并没有实现缓存机制。

验证代码:

Integer i1 = 33;
Integer i2 = 33;
System.out.println(i1 == i2);// 输出 true

Float i11 = 333f;
Float i22 = 333f;
System.out.println(i11 == i22);// 输出 false

Double i3 = 1.2;
Double i4 = 1.2;
System.out.println(i3 == i4);// 输出 false

Integer i1 = 40;
Integer i2 = new Integer(40);
System.out.println(i1==i2); //输出false

Integer i1=40 这一行代码会发生装箱,也就是说这行代码等价于 Integer i1=Integer.valueOf(40) 。因此,i1 直接使用的是缓存中的对象。而Integer i2 = new Integer(40) 会直接创建新的对象。 

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

 

Java中的包装类(Byte、Short、Integer、Long、Float、Double、Character、Boolean)都提供了常量池缓存机制,即对于某些范围内的数值,每次创建新的包装对象时并不会新建对象,而是从缓存中获取已有的对象引用。其中,Byte、Short、Integer、Long默认对[-128,127]之间的数值进行缓存,其他类默认不缓存。这样做的好处是可以节省内存开销,提高程序的性能。 例如,当我们使用以下方式创建Integer对象时,实际上并不会创建新的对象,而是从常量池中获取已有的对象引用: ``` Integer i1 = 10; // 自动装箱,相当于 Integer i1 = Integer.valueOf(10); Integer i2 = 10; // 自动装箱,相当于 Integer i2 = Integer.valueOf(10); System.out.println(i1 == i2); // true,因为 i1 和 i2 引用同一个对象 ``` 但是,当创建的数值超出了缓存范围时,就会创建新的对象,例如: ``` Integer i3 = 128; // 自动装箱,相当于 Integer i3 = Integer.valueOf(128); Integer i4 = 128; // 自动装箱,相当于 Integer i4 = Integer.valueOf(128); System.out.println(i3 == i4); // false,因为 i3 和 i4 引用不同的对象 ``` 需要注意的是,虽然使用包装类缓存机制可以提高程序的性能,但是在某些特殊情况下,也可能会导致程序出错。例如,如果使用包装类进行比较时,应该使用 equals() 方法进行比较,而不是使用“==”运算符进行比较。因为使用“==”运算符进行比较时,如果两个对象引用的不是同一个对象,就会返回 false,而不是根据对象的值进行比较。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值