Integer中的享元模式
本节我们来看一个例子,大家都非常熟悉的对象 Integer 也用到了享元模式,其中暗藏玄机,来看代码。
那么 JDK 为何要这么做呢?因为 -128~127 之间的数据在 int 范围内是使用最频繁的,为了减少频繁创建对象带来的内存消耗,这里就用到了享元模式,以提高性能。
上述例子中 a 和 b 的值为 100,因此会直接从 cache 中取已经存在的对象,所以 a 和 b 指向的是同一个对象,而 c 和 d 是分别指向不同的对象。
同理,Integer、Short、Byte、Character、Long 这几个类的 valueOf 方法的实现是类似的,而 Double、Float 的 valueOf 方法的实现是类似的,因为浮点数在某个范围内的个数不是有限的。
public static void main(String[] args) {
Integer a = Integer.valueOf(105);
Integer b = 105;
Integer c = Integer.valueOf(1000);
Integer d = 1000;
System.out.println("a==b:" + (a == b));
System.out.println("c==d:" + (c == d));
}
大家猜它的运行结果是什么?在运行完程序后,我们才发现有些不对,得到了一个意想不到的运行结果,如下图所示。
a==b:true
c==d:false
public final class Integer extends Number implements Comparable<Integer> {
...
public static Integer valueOf(int i) {
assert IntegerCache.high >= 127;
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
...
}
由上可知,Integer 源码中的 valueOf() 方法做了一个条件判断。在通过 valueof 方法创建 Integer 对象的时候,如果目标值在 -128~127 之间,则直接从缓存中取值,返回 IntegerCache.cache 中已经存在的对象的引用,否则新建 Integer 对象。那么 JDK 为何要这么做呢?因为 -128~127 之间的数据在 int 范围内是使用最频繁的,为了减少频繁创建对象带来的内存消耗,这里就用到了享元模式,以提高性能。
上述例子中 a 和 b 的值为 100,因此会直接从 cache 中取已经存在的对象,所以 a 和 b 指向的是同一个对象,而 c 和 d 是分别指向不同的对象。
同理,Integer、Short、Byte、Character、Long 这几个类的 valueOf 方法的实现是类似的,而 Double、Float 的 valueOf 方法的实现是类似的,因为浮点数在某个范围内的个数不是有限的。
拓展
和 Integer 类似,Long 源码也用到了享元模式,将 -128~127 的值缓存起来,源码如下:
public final class Long extends Number implements Comparable<Long> {
public static Long valueOf(long l) {
final int offset = 128;
if (l >= -128 && l <= 127) { // will cache
return LongCache.cache[(int)l + offset];
}
return new Long(l);
}
private static class LongCache {
private LongCache(){}
static final Long cache[] = new Long[-(-128) + 127 + 1];
static {
for(int i = 0; i < cache.length; i++)
cache[i] = new Long(i - 128);
}
}
...
}
同理,Long 中也有缓存,但是不能指定缓存最大值。所有教程
- C语言入门
- C语言编译器
- C语言项目案例
- 数据结构
- C++
- STL
- C++11
- socket
- GCC
- GDB
- Makefile
- OpenCV
- Qt教程
- Unity 3D
- UE4
- 游戏引擎
- Python
- Python并发编程
- TensorFlow
- Django
- NumPy
- Linux
- Shell
- Java教程
- 设计模式
- Java Swing
- Servlet
- JSP教程
- Struts2
- Maven
- Spring
- Spring MVC
- Spring Boot
- Spring Cloud
- Hibernate
- Mybatis
- MySQL教程
- MySQL函数
- NoSQL
- Redis
- MongoDB
- HBase
- Go语言
- C#
- MATLAB
- JavaScript
- Bootstrap
- HTML
- CSS教程
- PHP
- 汇编语言
- TCP/IP
- vi命令
- Android教程
- 区块链
- Docker
- 大数据
- 云计算