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
对象不是同一个对象
实例 自己实现一个缓存
1 2 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); } }
|