日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

如何在内存序列化中使用Java深克隆对象

發布時間:2023/12/3 java 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 如何在内存序列化中使用Java深克隆对象 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在我以前的文章中,我解釋了深度克隆和淺層克隆之間的區別 , 以及復制構造函數和防御性復制方法比默認的Java克隆更好。

使用復制構造函數和防御性復制方法進行的Java對象克隆當然具有某些優勢,但是我們必須顯式編寫一些代碼才能在所有這些方法中實現深度克隆。 而且,仍然有可能我們會錯過某些東西并且不會得到深克隆的對象。

正如在Java中創建對象的5種不同方式所討論的那樣,對序列化對象進行反序列化將創建一個狀態與序列化對象相同的新對象。 因此,與上述克隆方法類似,我們也可以使用對象序列化和反序列化來實現深度克隆功能,并且通過這種方法,我們不必擔心或編寫用于深度克隆的代碼,默認情況下會得到它。

但是,使用序列化克隆對象會帶來一些性能開銷,如果我們只需要克隆對象而不需要將其持久保存在文件中以備將來使用,則可以通過使用內存中序列化來改進它。

我們將使用以下Employee類作為示例,其name ,
作為狀態的doj和skills ,對于深度克隆,我們無需擔心code> name字段,因為它是String對象,默認情況下是all
弦在本質上是不變的 。

您可以在《 如何在Java中創建不可變的類》以及《 為什么String是不可變的和Final》上閱讀有關不可變性的更多信息。

Employee class implements Serializable { private static final long serialVersionUID = 2L; private String name; private LocalDate doj; private List<String> skills; public Employee(String name, LocalDate doj, List<String> skills) { this .name = name; this .doj = doj; this .skills = skills; } public String getName() { return name; } name; } public LocalDate getDoj() { return doj; } doj; } public List<String> getSkills() { return skills; } skills; } // Method to deep clone a object using in memory serialization public Employee deepClone() throws IOException, ClassNotFoundException { // First serializing the object and its state to memory using ByteArrayOutputStream instead of FileOutputStream. ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream out = new ObjectOutputStream(bos); out.writeObject( this ); // And then deserializing it from memory using ByteArrayOutputStream instead of FileInputStream. // Deserialization process will create a new object with the same state as in the serialized object, ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream in = new ObjectInputStream(bis); return (Employee) in.readObject(); } @Override public String toString() { return String.format( "Employee{name='%s', doj=%s, skills=%s}" , name, doj, skills); } @Override public boolean equals(Object o) { if ( this == o) return true ; if (o == null || getClass() != o.getClass()) return false ; Employee employee = (Employee) o; return Objects.equals(name, employee.name) && Objects.equals(doj, employee.doj) && Objects.equals(skills, employee.skills); } @Override public int hashCode() { return Objects.hash(name, doj, skills); } }

為了深度克隆Employee類的對象,我提供了一個
deepClone()方法,通過使用將對象序列化到內存
ByteArrayOutputStream而不是FileOutputStream并使用ByteArrayInputStream而不是FileInputStream將其反序列化。 在這里,我們將對象序列化為字節,然后再次將其從字節反序列化為對象。

Employee類實現Serializable接口來實現序列化,這有其自身的缺點,我們可以通過使用Externalizable接口自定義序列化過程來克服其中的一些缺點。

我們可以在下面的測試中運行,以了解我們的克隆方法是深層克隆還是淺層克隆,此處所有==操作將返回false(因為兩個對象是分開的),而所有equals將返回true(因為兩者具有相同的內容)。

public static void main(String[] args) throws IOException, ClassNotFoundException { Employee emp = new Employee( "Naresh Joshi" , LocalDate.now(), Arrays.asList( "Java" , "Scala" , "Spring" )); System.out.println( "Employee object: " + emp); // Deep cloning `emp` object by using our `deepClone` method. Employee clonedEmp = emp.deepClone(); System.out.println( "Cloned employee object: " + clonedEmp); System.out.println(); // All of this will print false because both objects are separate. System.out.println(emp == clonedEmp); System.out.println(emp.getDoj() == clonedEmp.getDoj()); System.out.println(emp.getSkills() == clonedEmp.getSkills()); System.out.println(); // All of this will print true because `clonedEmp` is a deep clone of `emp` and both have the same content. System.out.println(Objects.equals(emp, clonedEmp)); System.out.println(Objects.equals(emp.getDoj(), clonedEmp.getDoj())); System.out.println(Objects.equals(emp.getSkills(), clonedEmp.getSkills())); }

我們知道反序列化過程每次都會創建一個新對象,如果我們必須使我們的類單身,那將是不好的。 這就是為什么我們需要重寫和禁用單例類的序列化,這可以通過提供writeReplace和readResolve方法來實現。

與序列化類似,Java克隆也不能與單例模式一起使用,這就是為什么我們也需要覆蓋和禁用它。 我們可以通過實現克隆的方式來做到這一點,以便它要么拋出
CloneNotSupportedException或每次都返回相同的實例。

您可以在Java Cloning和Java上閱讀有關Java克隆和序列化的更多信息。
Java序列化主題。

您可以在此找到本文的完整源代碼。
Github存儲庫 ,請隨時提供寶貴的反饋。

翻譯自: https://www.javacodegeeks.com/2019/08/deep-clone-using-java-memory-serialization.html

總結

以上是生活随笔為你收集整理的如何在内存序列化中使用Java深克隆对象的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。