zoukankan      html  css  js  c++  java
  • JAVA整型包装类的缓存策略

    Java Integer的缓存策略

    public class JavaIntegerCache {
        public static void main(String... strings) {
     
            Integer integer1 = 3;
            Integer integer2 = 3;
     
            if (integer1 == integer2)
                System.out.println("integer1 == integer2");
            else
                System.out.println("integer1 != integer2");
     
            Integer integer3 = 300;
            Integer integer4 = 300;
     
            if (integer3 == integer4)
                System.out.println("integer3 == integer4");
            else
                System.out.println("integer3 != integer4");
     
        }
    }

    == 比较的是对象引用,而 equals 比较的是值。因此,在这个例子中,不同的对象有不同的引用,所以在进行比较的时候都应该返回 false。但是奇怪的是,这里两个相似的 if 条件判断却返回不同的布尔值。

    输出结果:

    integer1 == integer2
    integer3 != integer4

    Java 中 Integer 缓存实现:

    在 Java 5 中,为 Integer 的操作引入了一个新的特性,用来节省内存和提高性能。整型对象在内部实现中通过使用相同的对象引用实现了缓存和重用。

    上面的规则适用于整数区间 -128 到 +127。

    这种 Integer 缓存策略仅在自动装箱(autoboxing)的时候有用,使用构造器创建的 Integer 对象不能被缓存

    Java 编译器把原始类型自动转换为封装类的过程称为自动装箱(autoboxing),这相当于调用 valueOf 方法

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

    在创建新的 Integer 对象之前会先在 IntegerCache.cache 中查找。IntegerCache 类专门来负责 Integer 的缓存。

    IntegerCache 是 Integer 类中一个私有的静态类(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() {}
        }

      这个类是用来实现缓存支持,并支持 -128 到 127 之间的自动装箱过程。最大值 127 可以通过 JVM 的启动参数 -XX:AutoBoxCacheMax=size 修改缓存通过一个 for 循环实现。从小到大的创建尽可能多的整数并存储在一个名为 cache 的整数数组中。这个缓存会在 Integer 类第一次被使用的时候被初始化出来。以后,就可以使用缓存中包含的实例对象,而不是创建一个新的实例(在自动装箱的情况下)。

      实际上在 Java 5 中引入这个特性的时候,范围是固定的 -128 至 +127。后来在 Java 6 中,最大值映射到 java.lang.Integer.IntegerCache.high,可以使用 JVM 的启动参数设置最大值。选择这个 -128 到 127 这个范围,是因为这个范围的整数值是使用最广泛的。 在程序中第一次使用 Integer 的时候也需要一定的额外时间来初始化这个缓存。

    其他缓存的对象

    这种缓存行为不仅适用于Integer对象。我们针对所有整数类型的类都有类似的缓存机制。

    有 ByteCache 用于缓存 Byte 对象

    有 ShortCache 用于缓存 Short 对象

    有 LongCache 用于缓存 Long 对象

    有 CharacterCache 用于缓存 Character 对象

    Byte,Short,Long 有固定范围: -128 到 127。对于 Character, 范围是 0 到 127。除了 Integer 可以通过参数改变范围外,其它的都不行。

  • 相关阅读:
    三大主流负载均衡软件对比(LVS+Nginx+HAproxy)
    nginx 提示the "ssl" directive is deprecated, use the "listen ... ssl" directive instead
    centos安装nginx并配置SSL证书
    hadoop创建目录文件失败
    The server time zone value 'EDT' is unrecognized or represents more than one time zone.
    脚本启动SpringBoot(jar)
    centos做免密登录
    数据库远程连接配置
    Bash 快捷键
    TCP三次握手四次断开
  • 原文地址:https://www.cnblogs.com/pluto-yang/p/10483165.html
Copyright © 2011-2022 走看看