6.4.8 缓存实例的不可变类
缓存不可变类的实例的意义
不可变类的实例状态不可改变,可以很方便地被多个对象所共享。如果程序经常需要使用相同的不可变类实例,则应该考虑缓存这种不可变类的实例。毕竟重复创建相同的对象没有太大的意义,而且加大系统开销。如果可能,应该将已经创建的不可变类的实例进行缓存。
什么时候应该缓存
如果某个对象只使用一次,重复使用的概率不大,缓存该实例就弊大于利;反之,如果某个对象需要频繁地重复使用,缓存该实例就利大于弊。
Integer中的缓存
Java提供的java.lang.Integer类就采用了缓存,
- 如果采用new构造器来创建Integer对象,则每次返回全新的Integer对象;
- 如果采用valueOf()方法来创建Integer对象,则会缓存该方法创建的对象。
推荐使用valueOf方法创建Integer实例
- 由于通过new构造器创建Integer对象不会启用缓存,因此性能较差,Java9已经将该构造器标记为过时.
- 所以推荐是用valueOf()方法创建Integer对象
Integer缓存的范围
由于Integer只缓存负128到正127之间的Integer对象因此两次通过Integer.valueOf(200);方法生成的Integer对象不是同一个对象
实例 自己实现一个缓存
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 
 | class CacheImmutale {private static int MAX_SIZE = 10;
 
 private static CacheImmutale[] cache = new CacheImmutale[MAX_SIZE];
 
 private static int pos = 0;
 private final String name;
 
 private CacheImmutale(String name) {
 this.name = name;
 }
 
 public String getName() {
 return name;
 }
 
 public static CacheImmutale valueOf(String name) {
 
 for (int i = 0; i < MAX_SIZE; i++) {
 
 if (cache[i] != null && cache[i].getName().equals(name)) {
 return cache[i];
 }
 }
 
 if (pos == MAX_SIZE) {
 
 cache[0] = new CacheImmutale(name);
 
 pos = 1;
 } else {
 
 cache[pos++] = new CacheImmutale(name);
 }
 return cache[pos - 1];
 }
 
 public boolean equals(Object obj) {
 
 if (this == obj) {
 return true;
 }
 
 if (obj != null && obj.getClass() == CacheImmutale.class) {
 
 CacheImmutale ci = (CacheImmutale) obj;
 
 return name.equals(ci.getName());
 }
 return false;
 }
 
 public int hashCode() {
 return name.hashCode();
 }
 }
 
 public class CacheImmutaleTest {
 public static void main(String[] args) {
 CacheImmutale c1 = CacheImmutale.valueOf("hello");
 CacheImmutale c2 = CacheImmutale.valueOf("hello");
 
 System.out.println(c1 == c2);
 }
 }
 
 | 
原文链接: 6.4.8 缓存实例的不可变类