項目使用Ehcache來做爲程序和數據庫之間的緩衝, 使用過程當中會對cache對象作修改, 如plan.setLangSymbol(),發現後面使用cache的地方,取到的數據都是修改後的,因此猜想是cache的淺引用形成的。java
實際上,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。app
一種方法就是循環對象內容,將每一個屬性賦值給從新構建的新對象。工具
另外有個更簡單的方法,《A Java deep clone (deep copy) example》使用對象的序列化特性完成,看以下代碼:ui
/** * 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(); } }
很簡單!this