首页 > 编程语言 >Java Integer包装类缓存(cache)

Java Integer包装类缓存(cache)

时间:2024-02-04 23:15:04浏览次数:30  
标签:缓存 Java int cache System 127 println Integer

 

Java的Integer类有一个内部的缓存机制,主要用于优化自动装箱(autoboxing)和拆箱(unboxing)的性能。这个特性首次引入于Java 5,旨在减少对频繁使用的小整数值的重复对象创建,从而提高性能和减少内存使用。

 参数文档:Java Integer包装类缓存(cache)-CJavaPy

1、缓存范围

默认情况下,Integer缓存预先创建并存储了值在 -128 到 127 之间的整数对象。这个范围是固定的,因为它被定义为标准Java规范的一部分。-128 到 127 范围内的整数使用非常频繁,重用这些对象可以显著节省内存。

public class Main {
  public static void main(String[] args) {
	  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");

  }
}

2、自动装箱

Integer 类是 int 类型的包装类,它提供了一系列方法来操作 int 数据,并且是集合框架(如 ArrayList 和 HashMap)中使用的类。Java 为了优化性能和内存使用,在 Integer 类中实现了一个缓存机制,这个机制与自动装箱(Autoboxing)紧密相关。当一个基本类型的int值在这个范围内时,通过自动装箱转换为Integer对象,Java会直接从缓存中返回已存在的对象,而不是创建一个新的Integer实例。

public class Main {
  public static void main(String[] args) {
    Integer a = 100; // 自动装箱,使用缓存
    Integer b = 100; // 自动装箱,使用缓存
    System.out.println(a == b); // true,因为 a 和 b 指向相同的缓存对象
    
    Integer c = 200; // 自动装箱,不在缓存范围,创建新对象
    Integer d = 200; // 自动装箱,不在缓存范围,创建新对象
    System.out.println(c == d); // false,因为 c 和 d 指向不同的对象

  }
}

3、配置缓存大小

虽然标准的缓存大小是固定的,但是可以通过JVM启动参数 -XX:AutoBoxCacheMax=size 来设置缓存的上限。这允许缓存更大范围内的整数值,但应谨慎使用,因为这会增加JVM启动时的内存占用。

4、Java Integer包装类缓存的实现

Java 5 中引入了 Integer 包装类的缓存机制,旨在节省内存和提升性能。该机制对 -128 到 127 之间的 Integer 对象进行缓存,当需要使用在这个范围中某个值 的 Integer 对象时,会直接从缓存中返回,而不是每次都创建新的对象。Integer 类有一个名为 IntegerCache 的内部静态类,该类包含一个缓存数组,其中存储了 -128 到 127 之间的 Integer 对象。

Java JDK 1.8.0 build25的valueOf(int i)源码如下,

/**
     * Returns an {@code Integer} instance representing the specified
     * {@code int} value.  If a new {@code Integer} instance is not
     * required, this method should generally be used in preference to
     * the constructor {@link #Integer(int)}, as this method is likely
     * to yield significantly better space and time performance by
     * caching frequently requested values.
     *
     * This method will always cache values in the range -128 to 127,
     * inclusive, and may cache other values outside of this range.
     *
     * @param  i an {@code int} value.
     * @return an {@code Integer} instance representing {@code i}.
     * @since  1.5
     */
    public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

IntegerCache是在Integer类中私有的(private)静态内部类,代码如下,

 /**
     * Cache to support the object identity semantics of autoboxing for values between
     * -128 and 127 (inclusive) as required by JLS.
     *
     * The cache is initialized on first usage.  The size of the cache
     * may be controlled by the {@code -XX:AutoBoxCacheMax=} option.
     * During VM initialization, java.lang.Integer.IntegerCache.high property
     * may be set and saved in the private system properties in the
     * sun.misc.VM class.
     */
    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() {}
    }

5、其它包装类对象缓存

包装类缓存是不仅仅应用在Integer包装类对象,ByteCache缓存Byte对象,ShortCache缓存Short对象,LongCache缓存Long对象,CharacterCache缓存Character对象。

public class Main {
  public static void main(String[] args) {
        Byte b1 = 127;
        Byte b2 = 127;
        System.out.println(b1 == b2); // true

        Byte b3 = new Byte((byte) 127);
        System.out.println(b1 == b3); // false
        
        
        Short s1 = 127;
        Short s2 = 127;
        System.out.println(s1 == s2); // true

        Short s3 = new Short((short) 127);
        System.out.println(s1 == s3); // false
        
        
        Long l1 = 127L;
        Long l2 = 127L;
        System.out.println(l1 == l2); // true

        Long l3 = new Long(127L);
        System.out.println(l1 == l3); // false
        
        
        Character c1 = 'a';
        Character c2 = 'a';
        System.out.println(c1 == c2); // true

        Character c3 = new Character('a');
        System.out.println(c1 == c3); // false

  }
}

参数文档:Java Integer包装类缓存(cache)-CJavaPy

标签:缓存,Java,int,cache,System,127,println,Integer
From: https://www.cnblogs.com/tinyblog/p/18007183

相关文章

  • java----多线程
    1.什么是线程和进程?进程好比一个软件,线程好比软件中的一个功能。一个进程包含了多个线程,举例:比如360软件中木马查杀;买票的时候,火车站就是一个进程,各个窗口表示线程。并行与并发之间的区别:好比做饭吧,几个厨师分别同时做不同的食物-------------------并行---------------......
  • 【Java基础】Java线程的六种状态详解
    NEW状态当创建一个Thread对象但尚未调用其start()方法时,线程处于NEW状态。在这个状态下,线程并未启动,仅完成了初始化阶段。RUNNABLE状态RUNNABLE是Java中较为特殊的一个状态,它涵盖了传统操作系统中的就绪和运行两种状态。当线程已启动且CPU调度器为其分配了时间片或线程正在等待系......
  • Java 运算符详解与字符串处理技巧
    Java运算符算术运算符算术运算符用于执行常见的数学运算。运算符名称描述示例+加法将两个值相加x+y-减法从一个值中减去另一个值x-y*乘法将两个值相乘x*y/除法将一个值除以另一个值x/y%取模返回除法余数x%y++自增将变量......
  • Java并发(二十三)----同步模式之保护性暂停
    1、定义即GuardedSuspension,用在一个线程等待另一个线程的执行结果要点有一个结果需要从一个线程传递到另一个线程,让他们关联同一个GuardedObject如果有结果不断从一个线程到另一个线程那么可以使用消息队列JDK中,join的实现、Future的实现,采用的就是此模式因......
  • java Atomic原子类&&常见并发容器
    Atomic原子类Atomic原子类介绍Atomic翻译成中文是原子的意思。在这里Atomic是指一个操作是不可中断的。即使是在多个线程一起执行的时候,一个操作一旦开始,就不会被其他线程干扰。所以,所谓原子类说简单点就是具有原子/原子操作特征的类。并发包 java.util.concurrent 的原......
  • 非空处理 Java非空判断 非空处理及mysql数据库字段的not null
    1.mysql##去掉非空,如果非空又没有默认值,这样程序在添加数据的时候i,如果没有设置值就会报错。该操作很危险。##ALTERTABLE`order_test`ADDCOLUMN`test_card_name`NOTNULLVARCHAR(200)COMMENT'卡名称';##修改允许为空..ALTERTABLE`order_test`MODIFYCOLUMN`test......
  • 命令行,使用java的java 命令,直接调用执行class文件
    https://blog.csdn.net/sxzlc/article/details/104910162/目录0.最基本使用,参照下面链接(以前整理的资料)1.直接调用java文件■cmd2.调用jar包(MainClass打包到jar包时)方法一:java-jar xxx.jar方法二:java-cp ./xxx.jar  xxx.xxx.xx.MainClass3.补充说明4.运行时,设......
  • Java SPI 代码示例
    JavaServiceProviderInterface是JDK自带的服务提供者接口又叫服务发现机制更是一种面向接口的设计思想。即JDK本身提供接口类,第三方实现其接口,并作为jar包或其他方式注入到其中,在运行时会被JDKServiceLoader发现并加载,自动调用实现类的方法。1.在本地测试SPI机制本人......
  • [java] Tomcat 启动失败 Error: error while reading constant pool for .class: unex
    表现公司服务器今天启动tomcat失败,看catalina.out文件里面报错java.lang.ClassFormatError:Unknownconstanttag101inclassfilecn/world/data尝试解决查了一下,网上一般认为是字符串的问题,但是代码文件目标行是英文字符串,只是简单的println了字符串,应该不会有问题。尤......
  • Caused by: java.lang.IllegalStateException: A unix domain socket connection requ
    Causedby:java.lang.IllegalStateException:Aunixdomainsocketconnectionrequiresepollorkqueueandneitherisavailable出现这个错误,首先确保自己的操作系统是否支持epoll,或者kqueue。如果支持。请导入netty的大库,lettuce中好像缺失了一部分,我怀疑是这是怀疑,......