当前位置: 首页 > 编程笔记 >

Java包装类的缓存机制原理实例详解

端木野
2023-03-14
本文向大家介绍Java包装类的缓存机制原理实例详解,包括了Java包装类的缓存机制原理实例详解的使用技巧和注意事项,需要的朋友参考一下

这篇文章主要介绍了Java包装类的缓存机制原理实例详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

java 包装类的缓存机制,是在Java 5中引入的一个有助于节省内存、提高性能的功能,只有在自动装箱时有效

Integer包装类

举个栗子:

Integer a = 127;
Integer b = 127;
System.out.println(a == b);

这段代码输出的结果为true

使用自动装箱将基本类型转为封装类对象这个过程其实底层实现是调用封装类的valueOf方法:

Integer a =127; 相当于 Integer a = Integer.valueOf(127);

看一下Integer的valueOf方法:

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

如果入参 i 大于等于IntegerCache.low或者小于等于IntegerCache.high),就从IntegerCache中获取对象

看一下IntegerCache:

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之间,范围的最大值可以通过java.lang.Integer.IntegerCache.high设置,通过for循环将范围内的数据实例化为Integer对象放到cache数组里

在测试一下:

Integer a = 128;
Integer b = 128;
System.out.println(a == b);

输出结果为false,所以如果没有指定cache最大值时,在-128到127之间使用自动装箱时,会使用缓存

Byte包装类

再举个栗子:

public static void main(String[] args) {
  Byte a = 127;
  Byte b = 127;
  System.out.println(a == b); //true
}

由于Byte范围在-128到127之间,所以Byte的valueOf都是从ByteCache缓存中获取的

public static Byte valueOf(byte b) {
  final int offset = 128;
  return ByteCache.cache[(int)b + offset];
}

ByteCache类:

private static class ByteCache {
  private ByteCache(){}

  static final Byte cache[] = new Byte[-(-128) + 127 + 1];

  static {
    for(int i = 0; i < cache.length; i++)
      cache[i] = new Byte((byte)(i - 128));
  }
}

与IntegerCache相比,ByteCache的最大值是不能修改的就是127

Short包装类

public static Short valueOf(short s) {
  final int offset = 128;
  int sAsInt = s;
  if (sAsInt >= -128 && sAsInt <= 127) { // must cache
    return ShortCache.cache[sAsInt + offset];
  }
  return new Short(s);
}

ShortCache类:

private static class ShortCache {
  private ShortCache(){}

  static final Short cache[] = new Short[-(-128) + 127 + 1];

  static {
    for(int i = 0; i < cache.length; i++)
      cache[i] = new Short((short)(i - 128));
  }
}

ShortCache的最大值也不可以修改,范围只能在-128 ~ 127之间

Long包装类的valueOf方法和LongCache类与Short包装类的实现一致,范围也是只能在-128 ~ 127之间

Character包装类

valueOf方法:

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

CharacterCache类:

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);
  }
}

Character的缓存范围在0 ~ 127之间

Boolean包装类

valueOf方法:

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

TRUE跟FALSE都是static final修饰的静态变量

public static final Boolean TRUE = new Boolean(true);
public static final Boolean FALSE = new Boolean(false);

Float包装类 & Double包装类

valueOf方法:

public static Float valueOf(float f) {
  return new Float(f);
}
public static Double valueOf(double d) {
  return new Double(d);
}

Float和Double没有使用缓存,直接new的对象

总结:

java的包装类中:Byte,Short,Integer,Long,Character使用static代码块进行初始化缓存,其中Integer的最大值可以通过java.lang.Integer.IntegerCache.high设置;Boolean使用static final实例化的对象;Float和Double直接new的对象没有使用缓存

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小牛知识库。

 类似资料:
  • 本文向大家介绍Python代码块及缓存机制原理详解,包括了Python代码块及缓存机制原理详解的使用技巧和注意事项,需要的朋友参考一下 这篇文章主要介绍了Python代码块及缓存机制原理详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 1.相同的字符串在Python中地址相同 2.代码块: 所有的代码都需要依赖代码块执行。 ​ 一个模块,一个函

  • 本文向大家介绍Java实现LRU缓存的实例详解,包括了Java实现LRU缓存的实例详解的使用技巧和注意事项,需要的朋友参考一下 Java实现LRU缓存的实例详解 1.Cache Cache对于代码系统的加速与优化具有极大的作用,对于码农来说是一个很熟悉的概念。可以说,你在内存中new 了一个一段空间(比方说数组,list)存放一些冗余的结果数据,并利用这些数据完成了以空间换时间的优化目的,你就已经

  • 主要内容:1.AP 特性,2.服务状态,3.Eureka Server,4.缓存机制,5.Eureka Client,6.默认配置下服务消费者最长感知时间,7.网关实现服务下线实时感知1.AP 特性 从 CAP 理论看,Eureka 是一个 AP 系统,优先保证可用性(A)和分区容错性&sect;,不保证强一致性&copy;,只保证最终一致性,因此在架构中设计了较多缓存。 2.服务状态 Eureka 服务状态 enum 类:com.netflix.appinfo.InstanceInfo.Ins

  • 本文向大家介绍Java SPI机制原理及代码实例,包括了Java SPI机制原理及代码实例的使用技巧和注意事项,需要的朋友参考一下 SPI的全名为:Service Provider Interface,大多数开发人员可能不熟悉,因为这个是针对厂商或者插件的。在java.util.ServiceLoader的文档里有比较详细的介绍。 简单的总结下 Java SPI 机制的思想。我们系统里抽象的各个模

  • 本文向大家介绍Java Linkedlist原理及实例详解,包括了Java Linkedlist原理及实例详解的使用技巧和注意事项,需要的朋友参考一下 这篇文章主要介绍了Java Linkedlist原理及实例详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 定义:linkedlist属于链表结构,方便添加和删除元素,但查询不方便,适用于对收尾

  • 本文向大家介绍Java的回调机制实例详解,包括了Java的回调机制实例详解的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了Java的回调机制。分享给大家供大家参考,具体如下: 一 代码 二 运行 I've been called back 三 说明 回调机制的真正意图,就是实现控制反转,通过控制反转。对象在被创建的时候(如A处),由一个能够调控系统内所有对象的外界实体(如B处的caller