有关Ehcache的内容的引用和Java的deep copy

项目使用Ehcache来作为程序和数据库之间的缓冲, 使用过程中会对cache对象做修改, 如plan.setLangSymbol(),发现后面使用cache的地方,取到的数据都是修改后的,所以猜测是cache的浅引用造成的。

实际上,stackoverflow也有人提到此问题Cache.get() returns deep copy of element?

至于如何做deep copy,stackoverflow也提到Copying cached Map<String , List> object into temporary Map<String , List> object,经过实验,确认Guava的Maps.newHashMap(Map)工具类方法也是shallow copy。

一种方法就是循环对象内容,将每个属性赋值给重新构建的新对象。

另外有个更简单的方法,《A Java deep clone (deep copy) example》使用对象的序列化特性完成,看如下代码:

  /**
   * This method makes a "deep clone" of any object it is given.
   */
  public static Object deepClone(Object object) {
    try {
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      ObjectOutputStream oos = new ObjectOutputStream(baos);
      oos.writeObject(object);
      ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
      ObjectInputStream ois = new ObjectInputStream(bais);
      return ois.readObject();
    }
    catch (Exception e) {
      e.printStackTrace();
      return null;
    }
  }
}
 
/**
 * These classes implement Serializable so we can write them out and
 * read them back in as a stream of bytes.
 */
class Person implements Serializable {
  String firstName, lastName;
  Address address;
  public Person(String firstName, String lastName, Address address) {
    this.firstName = firstName;
    this.lastName = lastName;
    this.address = address;
  }
  public String toString() {
    StringBuilder sb = new StringBuilder();
    sb.append("First Name: " + firstName + "\n");
    sb.append("Last Name: " + lastName + "\n");
    sb.append("Street: " + address.street + "\n");
    return sb.toString();
  }
}

很简单!

posted on 2014-11-27 17:38  万木春  阅读(521)  评论(0编辑  收藏  举报

导航