面试官:你知道包装类的缓存机制吗?

简介: 面试官:你知道包装类的缓存机制吗?

面试官:你知道包装类的缓存机制吗?

缓存机制

包装类是对Java中基本类型的封装,在 JDK5 中引入了包装类的缓存机制,有助于节省内存。实现方式是在类初始化的时,提前创建好会频繁使用的包装类对象,当需要使用某个类的包装类对象时,如果该对象包装的值在缓存的范围内,就返回缓存的对象,否则就创建新的对象并返回。

使用构造函数创建对象时不使用缓存。例如:Integer a = new Integer(123);

在包装类中,浮点数类型的包装类Float,Double并没有实现常量池技术。

基本数据类型 包装类型 缓存范围
byte Byte -128 ~ 127
short Short -128 ~ 127
int Integer -128 ~ 127
long Long -128 ~ 127
char Character 0 ~ 127
boolean Boolean true,false
float Float
double Double

Long缓存

Long类中的缓存初始化源码如下所示:

private static class LongCache {
  private LongCache(){}
  // 缓存范围是 -128 到 127,因为有0的存在,所有需要 +1
  static final Long cache[] = new Long[-(-128) + 127 + 1];
  static {
    for(int i = 0; i < cache.length; i++)
      // 构造类实现的对象没有使用缓存
      cache[i] = new Long(i - 128);
  }
}

Integer 缓存

Integer 的缓存和 Long 略有不同,在 JDK6中,Integer的最大值可以使用 JVM 的启动参数设置最大值:-Djava.lang.Integer.IntegerCache.high=xxx

JDK源码

/**
 * 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=<size>} 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 {
    // 获取JVM启动时的参数
    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);
        // 缓冲区需要表示负数,所以假设设置int整数最大值的情况下,要去除负数和0的个数
        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() {}
}

缓存的使用

自动装箱的过程中是会使用缓存的,它的底层调用的是封装类的Integer.ValueOf(int i)方法

Integer源码

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

Long源码

public static Long valueOf(long l) {
  final int offset = 128;
  // 在 -128 和 127 范围内的数据会使用缓存
  if (l >= -128 && l <= 127) { 
    return LongCache.cache[(int)l + offset];
  }
  return new Long(l);
}

面试题

  1. 为什么使用整型包装类时,大家多推荐使用使用valueOf()方法,少使用parseXXX()方法?

因为 Integer、Long 这种包装类有缓存机制,valueOf 方法会从缓存中取值,如果命中缓存,会减少资源的开销,parseXXX 方法没有这个机制。

  1. switch语句能否作用在byte上,能否作用在long上,能否作用在string上?

byte的存储范围小于int,可以向int类型进行隐式转换,所以switch可以作用在byte上

long的存储范围大于int,不能向int进行隐式转换,只能强制转换,所以switch不可以作用在long上

string在1.7版本之前不可以,1.7版本之后switch就可以作用在string上了

目录
相关文章
|
2月前
|
缓存 Java 应用服务中间件
面试官:如何实现多级缓存?
面试官:如何实现多级缓存?
183 1
|
3月前
|
存储 缓存 前端开发
HTTP的缓存机制是什么?
HTTP的缓存机制是什么?
28 1
|
3月前
|
缓存 NoSQL Java
面试官:如何保证本地缓存的一致性?
面试官:如何保证本地缓存的一致性?
174 1
|
3月前
|
存储 消息中间件 缓存
redis的缓存机制
redis的缓存机制
92 0
|
11天前
|
XML 缓存 Java
MyBatis二级缓存解密:深入探究缓存机制与应用场景
MyBatis二级缓存解密:深入探究缓存机制与应用场景
46 2
MyBatis二级缓存解密:深入探究缓存机制与应用场景
|
1月前
|
存储 缓存 算法
深入探究LRU缓存机制:优化内存利用与提升性能
深入探究LRU缓存机制:优化内存利用与提升性能
129 1
|
1月前
|
存储 缓存 Java
什么!?实战项目竟然撞到阿里面试的原题!???关于MyBatis Plus的缓存机制
什么!?实战项目竟然撞到阿里面试的原题!???关于MyBatis Plus的缓存机制
|
3月前
|
Shell Unix Linux
Linux 终端命令之文件浏览(3) less
Linux 终端命令之文件浏览(3) less
30 0
Linux 终端命令之文件浏览(3) less
|
3月前
|
Java Go C++
Java每日一练(20230427) 螺旋矩阵、LRU缓存机制、解数独
Java每日一练(20230427) 螺旋矩阵、LRU缓存机制、解数独
26 0
Java每日一练(20230427) 螺旋矩阵、LRU缓存机制、解数独
|
3月前
|
Python 缓存 机器学习/深度学习
Python每日一练(20230331) 阶乘后的零、无重复最长子串、LRU缓存机制
Python每日一练(20230331) 阶乘后的零、无重复最长子串、LRU缓存机制
33 0
Python每日一练(20230331) 阶乘后的零、无重复最长子串、LRU缓存机制

热门文章

最新文章